for i in $(ls);do
if [ $i = '*.java' ];then
echo "I do something with the file $i"
fi
done
Saya ingin mengulang setiap file di folder saat ini dan memeriksa apakah cocok dengan ekstensi tertentu. Kode diatas tidak berfungsi, tahukah anda kenapa?
for i in $(ls *.java); do echo "do something with file $i"; done
?$i
dengan string literal "* .java"; perluasan pola tidak dilakukan di sini.if [[ $i == *.java ]]; then
.. (perhatikan tanda ganda [[]] s dan * .java tanpa tanda kutip).ls
- terima jawaban @ chepnerJawaban:
Tidak ada trik mewah yang dibutuhkan:
Penjaga memastikan bahwa jika tidak ada file yang cocok, loop akan keluar tanpa mencoba memproses nama file yang tidak ada
*.java
. Dalambash
(atau shell yang mendukung sesuatu yang serupa), Anda dapat menggunakannullglob
opsi untuk mengabaikan kecocokan yang gagal dan tidak memasuki isi loop.sumber
for i in *.java *.cpp; do
. Jika Anda telah mengaktifkan pola tambahanbash
denganshopt -s extglob
, Anda dapat menulisfor i in *.@(java|cpp); do
.shopt -s nullglob
agar pola yang tidak cocok meluas ke urutan kosong daripada diperlakukan secara harfiah.cd
ke direktori itu sebelum memulaifor
perulangannullglob
agar diperlakukan sebagai urutan kosong, atau mengaturnyafailglob
agar diperlakukan sebagai kesalahan. (Jika Anda menyetel keduanya,failglob
diutamakan.)jawaban yang benar adalah @ chepner's
Namun, berikut adalah trik kecil untuk memeriksa apakah nama file memiliki ekstensi tertentu:
sumber
ext
bukan.java
?Tambahkan subfolder secara berulang,
sumber
find . -name "*.java" -type f -exec echo \{\} \;
untuk menghindari kesalahan penguraian pada outputfind
"$i"
di dalam lingkaran.Loop melalui semua file yang berakhir dengan:
.img
,.bin
,.txt
akhiran, dan mencetak nama file:Atau secara rekursif (temukan juga di semua subdirektori):
sumber
Saya setuju dengan jawaban lain mengenai cara yang benar untuk mengulang melalui file. Namun OP bertanya:
Iya!
Artikel yang sangat baik Apa perbedaan antara test, [dan [[?] Menjelaskan secara rinci bahwa di antara perbedaan lainnya, Anda tidak dapat menggunakan
expression matching
ataupattern matching
dalamtest
perintah (yang merupakan singkatan dari[
)Jadi inilah alasan skrip Anda gagal. Jika OP tertarik dengan jawaban dengan
[[
sintaks (yang memiliki kelemahan karena tidak didukung pada banyak platform seperti[
perintah), saya akan dengan senang hati mengedit jawaban saya untuk memasukkannya.EDIT: Protips apa pun tentang cara memformat data dalam jawaban sebagai tabel akan sangat membantu!
sumber
seperti yang dikatakan @chepner dalam komentarnya Anda membandingkan $ i dengan string tetap.
Untuk memperluas dan memperbaiki situasi, Anda harus menggunakan [[]] dengan operator regex = ~
misalnya:
regex di sebelah kanan = ~ diuji terhadap nilai operator sebelah kiri dan tidak boleh dikutip, (dikutip tidak akan salah tetapi akan dibandingkan dengan string tetap dan kemungkinan besar akan gagal "
tetapi jawaban @chepner di atas menggunakan glob adalah mekanisme yang jauh lebih efisien.
sumber
ext
bukan.java
?if [[ $i == *.java ]]
atauif [[ $i == *.$ext ]]
. Tapi jangan parsing lsSaya menemukan solusi ini cukup berguna. Ini menggunakan
-or
opsi difind
:find . -name \*.tex -or -name "*.png" -or -name "*.pdf"
Ini akan menemukan file dengan ekstensi
tex
,png
danpdf
.sumber