TL; DR: Jika Anda hanya di sini untuk jawaban yang paling benar, Anda mungkin menginginkan preferensi pribadi saya, find . -name '*.txt' -exec process {} \;
(lihat bagian bawah posting ini). Jika Anda punya waktu, baca sisanya untuk melihat beberapa cara berbeda dan masalah dengan sebagian besar dari mereka.
Jawaban lengkapnya:
Cara terbaik tergantung pada apa yang ingin Anda lakukan, tetapi di sini ada beberapa pilihan. Selama tidak ada file atau folder di subtree yang memiliki spasi putih dalam namanya, Anda bisa memutarnya:
for i in $x; do # Not recommended, will break on whitespace
process "$i"
done
Secara marginal lebih baik, hilangkan variabel sementara x
:
for i in $(find -name \*.txt); do # Not recommended, will break on whitespace
process "$i"
done
Jauh lebih baik untuk glob ketika Anda bisa. Brankas ruang putih, untuk file di direktori saat ini:
for i in *.txt; do # Whitespace-safe but not recursive.
process "$i"
done
Dengan mengaktifkan globstar
opsi ini, Anda dapat menggumpalkan semua file yang cocok di direktori ini dan semua subdirektori:
# Make sure globstar is enabled
shopt -s globstar
for i in **/*.txt; do # Whitespace-safe and recursive
process "$i"
done
Dalam beberapa kasus, misalnya jika nama file sudah ada dalam file, Anda mungkin perlu menggunakan read
:
# IFS= makes sure it doesn't trim leading and trailing whitespace
# -r prevents interpretation of \ escapes.
while IFS= read -r line; do # Whitespace-safe EXCEPT newlines
process "$line"
done < filename
read
dapat digunakan dengan aman dalam kombinasi dengan find
dengan mengatur pembatas secara tepat:
find . -name '*.txt' -print0 |
while IFS= read -r -d '' line; do
process "$line"
done
Untuk pencarian yang lebih kompleks, Anda mungkin ingin menggunakan find
, baik dengan -exec
opsi atau dengan -print0 | xargs -0
:
# execute `process` once for each file
find . -name \*.txt -exec process {} \;
# execute `process` once with all the files as arguments*:
find . -name \*.txt -exec process {} +
# using xargs*
find . -name \*.txt -print0 | xargs -0 process
# using xargs with arguments after each filename (implies one run per filename)
find . -name \*.txt -print0 | xargs -0 -I{} process {} argument
find
juga dapat melakukan cd ke direktori masing-masing file sebelum menjalankan perintah dengan menggunakan -execdir
alih-alih -exec
, dan dapat dibuat interaktif (meminta sebelum menjalankan perintah untuk setiap file) menggunakan -ok
alih-alih -exec
(atau -okdir
bukannya -execdir
).
*: Secara teknis, keduanya find
dan xargs
(secara default) akan menjalankan perintah dengan argumen sebanyak yang sesuai pada baris perintah, sebanyak yang diperlukan untuk melewati semua file. Dalam praktiknya, kecuali jika Anda memiliki jumlah file yang sangat besar itu tidak masalah, dan jika Anda melebihi panjangnya tetapi membutuhkan semuanya pada baris perintah yang sama, Anda SOL menemukan cara yang berbeda.