Idealnya Anda tidak melakukannya sama sekali, karena mem-parsing nama file dengan benar dalam skrip shell selalu sulit (perbaiki untuk spasi, Anda masih akan mengalami masalah dengan karakter tersemat lainnya, khususnya baris baru). Ini bahkan terdaftar sebagai entri pertama di halaman BashPitfalls.
Yang mengatakan, ada cara untuk hampir melakukan apa yang Anda inginkan:
oIFS=$IFS
IFS=$'\n'
find . -name '*.txt' | while read -r i; do
# use "$i" with whatever you're doing
done
IFS=$oIFS
Ingat juga untuk mengutip $i
saat menggunakannya, untuk menghindari hal-hal lain yang menafsirkan ruang nanti. Ingatlah juga untuk menyetel $IFS
kembali setelah menggunakannya, karena tidak melakukannya akan menyebabkan kesalahan yang membingungkan nantinya.
Ini memang memiliki satu peringatan lain:apa yang terjadi di dalam while
loop dapat terjadi dalam subkulit, tergantung pada shell persis yang Anda gunakan, sehingga pengaturan variabel mungkin tidak bertahan. for
versi loop menghindari itu tetapi dengan harga itu, bahkan jika Anda menerapkan $IFS
solusi untuk menghindari masalah dengan spasi, Anda kemudian akan mendapat masalah jika find
mengembalikan terlalu banyak file.
Pada titik tertentu, perbaikan yang benar untuk semua ini adalah melakukannya dalam bahasa seperti Perl atau Python, bukan shell.
Gunakan find -print0
dan kirimkan ke xargs -0
, atau tulis program C kecil Anda sendiri dan kirimkan ke program C kecil Anda. Inilah yang -print0
dan -0
diciptakan untuk.
Skrip Shell bukan cara terbaik untuk menangani nama file dengan spasi di dalamnya:Anda bisa melakukannya, tetapi akan menjadi kikuk.
Anda dapat menyetel "pemisah bidang internal" (IFS
) ke selain ruang untuk pemisahan argumen pengulangan, mis.
ORIGIFS=${IFS}
NL='
'
IFS=${NL}
for i in $(find . -name '*.txt'); do
IFS=${ORIGIFS}
#do stuff
done
IFS=${ORIGIFS}
Saya mereset IFS
setelah digunakan di find, kebanyakan karena tampilannya bagus, menurut saya. Saya belum melihat masalah dalam mengaturnya ke baris baru, tapi menurut saya ini "lebih bersih".
Metode lain, tergantung pada apa yang ingin Anda lakukan dengan output dari find
, adalah menggunakan -exec
secara langsung dengan find
perintah, atau gunakan -print0
dan kirimkan ke xargs -0
. Dalam kasus pertama find
menangani nama file yang keluar. Di -print0
kasus, find
mencetak hasilnya dengan pemisah null, lalu xargs
terpecah dalam hal ini. Karena tidak ada nama file yang dapat berisi karakter itu (yang saya tahu), ini juga selalu aman. Ini sebagian besar berguna dalam kasus sederhana; dan biasanya bukan pengganti yang bagus untuk for
lengkap lingkaran.