Bash shell: daftar semua file bertipe .png atau .PNG?

14

Dalam skrip bash, bagaimana saya bisa mengatakan 'untuk semua file bertipe .png atau .PNG'?

Saya mencoba :

for i in (`ls *.PNG` && `ls *.png`)

tetapi mendapatkan kesalahan sintaksis.

simon
sumber

Jawaban:

18

Jika Anda ingin semua kemungkinan kombinasi, gunakan:

for i in *.[Pp][Nn][Gg]; do

atau

shopt -s nocaseglob
for i in *.png; do

meskipun itu akan membuat semua gumpalan shell skrip Anda (yaitu file wildcard cocok) case sensitif sampai Anda menjalankan shopt -u nocaseglob.

Jika Anda benar-benar hanya ingin .PNG dan .png (dan tidak, misalnya, .PnG atau .pnG), maka gunakan

shopt -s nullglob
for i in *.png *.PNG; do

atau

for i in *.png *.PNG; do
    [[ -e "$i" ]] || continue

... alasan untuk nullglob atau pemeriksaan keberadaan adalah bahwa jika Anda hanya memiliki ekstensi huruf kecil atau hanya huruf besar, itu akan menyertakan pola yang tidak cocok dalam daftar file, yang mengarah ke kesalahan dalam tubuh loop. Seperti halnya nocaseglob, Anda mungkin ingin mematikan opsi shell nullglob sesudahnya (walaupun menurut pengalaman saya, nullglob on sering kali baik, terutama dalam skrip). Sebenarnya, saya lebih suka menggunakan nocaseglob atau cek keberadaan untuk semua kecocokan file seperti ini, kalau-kalau tidak ada kecocokan.

Gordon Davisson
sumber
5
for i in *.{png,PNG}
glenn jackman
@glenn: Itu akan berhasil juga (setara dengan `* .png * .PNG), meskipun Anda masih memerlukan nullglob atau pemeriksaan keberadaan.
Gordon Davisson
5

Anda juga dapat mencoba beberapa lapisan seperti

Temukan . -iname "* .png" -exec ....

atau

Temukan . -iname "* .png" | xargs ....

Sunting
Lihat juga komentar @ Yab di bawah tentang rekursi.

Alain Pannetier
sumber
1
Namun menemukan secara default bersifat rekursif, jadi untuk mendapatkan hasil yang sama dengan pertanyaan, Anda harus melakukannya find -maxdepth 1 -iname "*.png"
Yab
@Yab, kamu benar sekali. Saya mengabaikan aspek ini.
Alain Pannetier
1

ls hampir tidak berguna di sini tetapi untuk catatan di sini ada sintaks yang lebih dekat dengan upaya Anda:

for i in $(ls *.PNG ; ls *.png)

Catatan:

  • Saya berasumsi Anda menginginkan gambar besar dan kecil. Pemisah && akan berarti memproses file png hanya jika file PNG ada, yang mungkin tidak masuk akal.
  • Anda akan memiliki pesan kesalahan ditampilkan jika tidak ada file yang ditemukan dengan pola yang baik.
Jlliagre
sumber