Anda bisa menggunakan globstar.
Dengan globstar
opsi shell diaktifkan, yang Anda butuhkan adalah gzip -vk **/*.{css,html}
.
Bash shell memiliki globstar
opsi yang memungkinkan Anda menulis rekursif gumpalan dengan **
. shopt -s globstar
memungkinkannya. Tapi Anda mungkin tidak ingin melakukan itu untuk perintah lain yang Anda jalankan nanti, jadi Anda bisa menjalankannya dan gzip
perintah Anda dalam subkulit sebagai gantinya.
Perintah ini gzip
s semua .css
dan .html
file dalam direktori saat ini salah satu subdirektorinya, salah mereka subdirektori, dll, menjaga file asli ( -k
) dan memberitahu Anda apa yang dilakukannya ( -v
):
(shopt -s globstar; gzip -vk **/*.{css,html})
Jika Anda ingin mencocokkan nama file dengan case-insensitive sehingga ekstensi dengan beberapa atau semua huruf besar disertakan, maka Anda juga dapat mengaktifkan nocaseglob
opsi shell:
(shopt -s globstar nocaseglob; gzip -vk **/*.{css,html})
;
memisahkan dua perintah, dan bagian luar (
)
menyebabkannya dijalankan dalam subkulit. Mengatur opsi shell di subkulit tidak menyebabkannya diatur dalam shell panggilan. Jika Anda tidak ingin mengaktifkan globstar
maka Anda dapat menjalankan shopt -s globstar
; maka Anda bisa menjalankan perintah:
gzip -vk **/*.{css,html}
Anda dapat menonaktifkan globstar
dengan shopt -u globstar
. Anda dapat memeriksa apakah saat ini diaktifkan dengan shopt globstar
.
Bagaimana itu bekerja
Kunci untuk bagaimana gzip
perintah ini bekerja adalah bahwa shell melakukan ekspansi di atasnya untuk menghasilkan daftar setiap file dalam hierarki direktori dengan nama yang cocok, kemudian melewati masing-masing nama file ini sebagai argumen gzip
.
- Ekspansi brace berubah
**/*.{css,html}
menjadi **/*.css **/*.html
.
- Kemudian globbing memperluas kedua pola menjadi nama-nama file yang dapat diakses di bawah direktori saat ini (
**
, karena globstar
) yang nama filenya terdiri dari apa saja ( *
) diikuti oleh akhiran yang ditentukan ( .css
atau .html
dalam kasus ini).
Ini tidak cocok dengan file yang namanya dimulai dengan.
atau yang berada di direktori bernama cara ini. Anda mungkin tidak memiliki file HTML dan CSS tersebut dan, jika Anda melakukannya, Anda mungkin tidak ingin memasukkannya. Tetapi jika Anda ingin memasukkannya, maka Anda dapat mencocokkannya secara eksplisit tergantung pada kebutuhan Anda. Misalnya, mengubah **/*.{css,html}
ke **/{,.}*.{css,html}
termasuk file yang dimulai dengan .
saat masih belum mencari di folder yang melakukan.
Jika Anda ingin kedua file yang namanya mulai .
dan file dalam direktori yang namanya mulai .
dimasukkan, ada cara yang lebih bersih dan sederhana: aktifkan dotglob
opsi shell.
(shopt -s globstar dotglob; gzip -vk **/*.{css,html})
Atau jika Anda ingin pencocokan huruf besar-kecil dan pencocokan nama file yang dimulai dengan .
:
(shopt -s globstar nocaseglob dotglob; gzip -vk **/*.{css,html})
Mungkin saja, meskipun sangat jarang, untuk **
memperluas ke sesuatu yang terlalu lama.
Jika Anda memiliki sejumlah besar file bernama cara ini, maka ini mungkin gagal dengan pesan kesalahan yang menjelaskan bahwa shell tidak dapat membangun baris perintah karena itu akan terlalu lama. (Bahkan dengan ribuan file, ini biasanya tidak masalah.)
gzip
tidak akan dipanggil sama sekali, sehingga Anda tidak akan mendapatkan pekerjaan setengah jadi.
Jika kesalahan ini terjadi, atau jika Anda khawatir tentang hal itu, Anda dapat menggunakannya find
dengan -exec
, seperti yang dijelaskan steeldriver (dengan {} \;
) atau seperti yang saya jelaskan di bawah (dengan {} +
).
Anda dapat menggunakannya find
dengan -exec
aksi dan +
untuk efisiensi.
The gzip
mendukung perintah yang diberikan nama-nama beberapa file yang akan dikompresi. Tetapi find
perintah ini , meskipun bekerja dengan baik dan tidak akan lambat kecuali jika Anda memiliki banyak file, jalankan gzip
perintah sekali untuk setiap file:
find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} \;
Ini berfungsi, dan Anda pasti bisa menggunakannya. ( .
mencari dari direktori saat ini. Selain itu, ini benar-benar cara menulis perintah dalam jawaban steeldriver yang sangat bagus ; Anda dapat menggunakan gaya apa pun yang Anda inginkan.)
Anda juga dapat membuat find
beberapa nama file lewat gzip
dan menjalankannya hanya sebanyak yang diperlukan - yang hampir selalu hanya sekali. Untuk melakukannya, gunakan +
sebagai ganti\;
. The +
Argumen harus datang hanya setelah {}
. find
ganti +
dengan nama file tambahan, jika ada.
find . \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +
Tidak masalah untuk menggunakan +
bahkan jika hanya ada beberapa file yang cocok, dan ketika ada banyak dari mereka, itu bisa terasa lebih cepat daripada memiliki gzip
doa terpisah untuk setiap file.
Seperti disebutkan steeldriver , Anda dapat menggunakan -iname
alih-alih -name
mencocokkan file yang namanya suka .css
atau .html
tetapi dengan huruf besar berbeda. Ini sesuai dengan mengaktifkan nocaseglob
dalam globstar
metode berbasis yang dijelaskan di atas.
Terakhir, Anda mungkin tidak memiliki file atau direktori yang cocok dengan yang dimulai .
. Tetapi jika Anda melakukannya, find
secara otomatis memasukkan mereka. Jika Anda ingin mengecualikan mereka (seperti yang terjadi pada globstar
metode -based yang dijelaskan di atas ketika dotglob
dimatikan), Anda dapat :
find . -not -path '*/.*' \( -name \*.css -o -name \*.html \) -exec gzip -vk {} +
Cara globstar
berbasis-yang dijelaskan di atas lebih mudah untuk ditulis, terutama jika Anda mengecualikan direktori dan file yang dimulai dengan .
, karena itulah defaultnya.
Apa yang tidak boleh dilakukan ...
Nama file dapat berisi karakter apa pun kecuali pemisah jalur /
dan karakter nol . Ada banyak teknik yang merusak nama file aneh, dan mereka biasanya lebih rumit daripada teknik yang selalu berhasil. Jadi saya sarankan menghindari mereka bahkan ketika Anda tahu (atau berpikir Anda tahu) mereka baik-baik saja dalam situasi spesifik Anda. Dan tentu saja Anda tidak boleh menggunakannya jika Anda mungkin memiliki nama file dengan karakter yang dapat diperlakukan secara khusus, termasuk spasi.
Dimungkinkan untuk mem-pipe output dengan aman find
ke perintah lain yang memprosesnya jika Anda menggunakan -print0
atau tindakan serupa untuk menyebabkannya menempatkan karakter nol di antara path sebagai ganti baris baru , dan bukan sebaliknya. Nama file dapat berisi baris baru (meskipun saya tidak menyarankan Anda untuk memberi nama file dengan sengaja). Sebuah find
perintah dengan -print
tindakan - termasuk perintah find dengan tidak ada tindakan eksplisit, sejak itu -print
adalah default - tidak menghasilkan output yang aman dapat disalurkan atau diberikan kepada perintah lain yang melakukan tindakan pada file.
Output yang find
dihasilkan dengan -print0
action dapat dengan aman disalurkan ke xargs -0
( -0
flag memberitahu xargs
untuk mengharapkan input yang dipisahkan nol).
-r
berfungsi seperti yang dirancang. Dari man gzip : Jelajahi struktur direktori secara rekursif. Jika salah satu nama file yang ditentukan pada baris perintah adalah direktori , gzip akan turun ke direktori dan kompres semua file yang ditemukannya di sana (atau dekompres mereka dalam kasus gunzip). (penekanan pada saya)