Saya pikir ini akan sederhana - tetapi terbukti lebih kompleks dari yang saya harapkan.
Saya ingin mengulang semua file dari jenis tertentu dalam direktori, jadi saya menulis ini:
#!/bin/bash
for fname in *.zip ; do
echo current file is ${fname}
done
Ini berfungsi selama ada setidaknya satu file yang cocok dalam direktori. Namun jika tidak ada file yang cocok, saya mendapatkan ini:
current file is *.zip
Saya kemudian mencoba:
#!/bin/bash
FILES=`ls *.zip`
for fname in "${FILES}" ; do
echo current file is ${fname}
done
Sementara badan loop tidak dieksekusi ketika tidak ada file, saya mendapatkan kesalahan dari ls:
ls: *.zip: No such file or directory
Bagaimana cara menulis loop yang dengan bersih menangani tidak ada file yang cocok?
shopt -s nullglob
sebelum menjalankan loop for.FILES=
ls * .zip; for fname in "${FILES}"...
tetapi berfungsi seperti yang diharapkan denganfor fname in *.zip ; do....
for file in *.zip
, bukan`ls ...`
. Saran @ cuonglm adalah agar tidak*.zip
berkembang ketika pola tidak cocok dengan file apa pun.ls
tanpa argumen daftar direktori saat ini.ls
umumnya harus dihindari: Mengapa tidak parsingls
? ; juga melihat tautan di dekat bagian atas halaman itu ke artikel ParsingLs BashGuide .Jawaban:
Di
bash
, Anda dapat mengaturnullglob
opsi sehingga pola yang tidak cocok dengan apa pun "menghilang", daripada diperlakukan sebagai string literal:Dalam skrip POSIX shell, Anda hanya memverifikasi yang
fname
ada (dan pada saat yang sama dengan[ -f ]
, periksa itu adalah file biasa (atau symlink ke file biasa) dan bukan jenis lain seperti direktori / fifo / perangkat ...):Ganti
[ -f "$fname" ]
dengan[ -e "$fname" ] || [ -L "$fname ]
jika Anda ingin mengulang semua file (tidak disembunyikan) yang namanya berakhir.zip
terlepas dari jenisnya.Ganti
*.zip
dengan.*.zip .zip *.zip
jika Anda juga ingin mempertimbangkan file tersembunyi yang namanya berakhir.zip
.sumber
shopt -s nullglob
tidak bekerja untuk saya di Ubuntu 17.04, tetapi[ -f "$fname" ] || continue
bekerja dengan baik.bash
.Dalam komentar di sini Anda menyebutkan memohon suatu fungsi ...
sumber
Gunakan temukan
Anda HARUS mengekspor fungsi shell Anda
export -f
agar ini berfungsi. Sekarangfind
jalankanbash
yang mengeksekusi fungsi shell Anda, dan tetap pada level dir saat ini saja.sumber
Dari pada:
Mencoba:
Dengan cara ini jika ls gagal (yang tidak dalam kasus Anda) itu akan menerima output yang gagal dan kembali sebagai variabel kosong.
Anda dapat menambahkan beberapa logika untuk membuatnya mengembalikan "Tidak Ada File Ditemukan"
Dengan cara ini jika perintah sebelumnya berhasil (keluar dengan nilai 0) maka itu akan mencetak file saat ini, jika tidak maka akan mencetak "Tidak Ada File Ditemukan"
sumber
grep
) daripada mencoba memperbaiki masalah dengan menggunakan alat yang lebih baik (find
) atau mengubah pengaturan yang relevan untuk solusi saat ini (denganshopt -s nullglob
)shopt -s nullglob
itu tidak berfungsi. Saya mencobafind
sambil memverifikasi jawaban saya dan terus gagal. Saya pikir karena ekspor, kata Dani.