TL; DR: En doğru cevap için buradaysanız, muhtemelen kişisel tercihimi istiyorsunuz find . -name '*.txt' -exec process {} \;
(bu yazının altına bakınız). Zamanınız varsa, birçok farklı yol ve bunların çoğundaki sorunları görmek için geri kalanını okuyun.
Tam cevap:
En iyi yol ne yapmak istediğinize bağlıdır, ancak işte birkaç seçenek. Alt ağaçtaki hiçbir dosya veya klasör adında boşluk içermediği sürece, dosyalar üzerinde döngü yapabilirsiniz:
for i in $x; do # Not recommended, will break on whitespace
process "$i"
done
Marjinal olarak daha iyi, geçici değişkeni kesin x
:
for i in $(find -name \*.txt); do # Not recommended, will break on whitespace
process "$i"
done
Mümkün olduğunda glob yapmak çok daha iyidir. Geçerli dizindeki dosyalar için beyaz boşluk kasası:
for i in *.txt; do # Whitespace-safe but not recursive.
process "$i"
done
globstar
Seçeneği etkinleştirerek, bu dizindeki ve tüm alt dizinlerdeki tüm eşleşen dosyaları glob edebilirsiniz:
# Make sure globstar is enabled
shopt -s globstar
for i in **/*.txt; do # Whitespace-safe and recursive
process "$i"
done
Bazı durumlarda, örneğin dosya adları zaten bir dosyadaysa, şunları kullanmanız gerekebilir 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
find
sınırlayıcıyı uygun şekilde ayarlayarak güvenli bir şekilde birlikte kullanılabilir :
find . -name '*.txt' -print0 |
while IFS= read -r -d '' line; do
process "$line"
done
Daha karmaşık aramalar için, muhtemelen kullanmak isteyeceğiniz find
onun ile ya -exec
seçenek veya birlikte -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
-execdir
yerine kullanarak bir komutu çalıştırmadan önce her dosyanın dizinine cd yapabilir -exec
ve -ok
yerine -exec
(veya -okdir
yerine ) kullanarak etkileşimli (her dosya için komutu çalıştırmadan önce sor -execdir
) yapılabilir.
*: Teknik olarak, hem find
ve xargs
(varsayılan olarak) komutu komut satırına sığabilecek kadar çok argümanla çalıştırır, tüm dosyaları almak için gereken kadar. Uygulamada, çok fazla sayıda dosyanız yoksa, önemli olmayacaktır ve uzunluğu aşar ancak hepsine aynı komut satırında ihtiyacınız varsa, SOL farklı bir yol bulur.