Pengulangan secara berulang melalui file dalam direktori dapat dengan mudah dilakukan dengan:
find . -type f -exec bar {} \;
Namun, di atas tidak bekerja untuk hal-hal yang lebih kompleks, di mana banyak cabang bersyarat, perulangan dll perlu dilakukan. Saya menggunakan ini untuk hal di atas:
while read line; do [...]; done < <(find . -type f)
Namun, sepertinya ini tidak berfungsi untuk file yang berisi karakter tidak jelas:
$ touch $'a\nb'
$ find . -type f
./a?b
Apakah ada alternatif yang menangani karakter tidak jelas seperti itu dengan baik?
find ... -exec bash -c 'echo filename is in \$0: "$0"' {} \;
adalah cara yang lebih baik untuk melakukannya.read line
keIFS= read -r line
. Satu-satunya karakter yang akan memecahnya adalah baris baru.-d $'\0'
lebih disukai.Jawaban:
Penggunaan lain untuk keamanan
find
:(Ini berfungsi dengan POSIX apa pun
find
, tetapi bagian shell memerlukan bash. Dengan * BSD dan GNU find, Anda dapat menggunakannya-print0
sebagai gantinya-exec printf '%s\0' {} +
, itu akan sedikit lebih cepat.)Ini memungkinkan untuk menggunakan input standar di dalam loop, dan bekerja dengan jalur apa pun .
sumber
do echo "Filename is '$REPLY'"
Melakukan ini sesederhana:
Atau...
sumber
Pendekatan paling sederhana (namun aman) adalah dengan menggunakan shell globbing:
Untuk membuat perulangan di atas ke dalam subdirektori (dalam bash), Anda dapat menggunakan
globstar
opsi; juga diaturdotglob
untuk mencocokkan file yang namanya dimulai dengan.
:Berhati-hatilah bahwa hingga bash 4.2,
**/
berulang menjadi tautan simbolis ke direktori. Sejak bash 4.3,**/
berulang hanya ke direktori, sepertifind
.Solusi lain yang umum adalah untuk digunakan
find -print0
denganxargs -0
:Perhatikan bahwa
h:/g
sebenarnya sudah benar karena nama file berisi a\r
.sumber
Agak sulit untuk melakukan loop baca Anda dengan mudah, tetapi untuk bash khususnya Anda dapat mencoba sesuatu seperti ini .
Bagian yang relevan:
Itu menginstruksikan
find
untuk mencetak keluarannya yang dibatasi oleh karakter NUL (0x00), danread
untuk mengambil garis yang dibatasi NUL (-d $'\0'
) tanpa menangani garis miring terbalik sebagai lolos dari karakter lain (-r
) dan tidak melakukan pemisahan kata pada baris (IFS=
). Karena 0x00 adalah byte yang tidak dapat terjadi di nama file atau jalur di Unix, ini harus menangani semua masalah nama file aneh Anda.sumber
-d ''
setara dengan-d $'\0'
.