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 globstaropsi 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
readdapat digunakan dengan aman dalam kombinasi dengan finddengan 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 -execopsi 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
findjuga dapat melakukan cd ke direktori masing-masing file sebelum menjalankan perintah dengan menggunakan -execdiralih-alih -exec, dan dapat dibuat interaktif (meminta sebelum menjalankan perintah untuk setiap file) menggunakan -okalih-alih -exec(atau -okdirbukannya -execdir).
*: Secara teknis, keduanya finddan 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.