TL; DR: ถ้าคุณมาที่นี่เพื่อหาคำตอบที่ถูกต้องที่สุดคุณอาจต้องการความชอบส่วนตัวของฉันfind . -name '*.txt' -exec process {} \;
(ดูที่ด้านล่างของโพสต์นี้) หากคุณมีเวลาอ่านส่วนที่เหลือเพื่อดูวิธีที่แตกต่างและปัญหากับพวกเขาส่วนใหญ่
คำตอบแบบเต็ม:
วิธีที่ดีที่สุดขึ้นอยู่กับสิ่งที่คุณต้องการทำ แต่นี่คือตัวเลือกบางอย่าง ตราบใดที่ไม่มีไฟล์หรือโฟลเดอร์ในทรีย่อยมีช่องว่างในชื่อคุณสามารถวนซ้ำไฟล์ได้:
for i in $x; do # Not recommended, will break on whitespace
process "$i"
done
ตัดขอบตัวแปรชั่วคราวให้ดีขึ้นx
:
for i in $(find -name \*.txt); do # Not recommended, will break on whitespace
process "$i"
done
มันจะดีกว่ามากเมื่อคุณสามารถทำตาม White-space safe สำหรับไฟล์ในไดเรกทอรีปัจจุบัน:
for i in *.txt; do # Whitespace-safe but not recursive.
process "$i"
done
ด้วยการเปิดใช้งานglobstar
ตัวเลือกนี้คุณสามารถ glob ไฟล์ที่ตรงกันทั้งหมดในไดเรกทอรีนี้และไดเรกทอรีย่อยทั้งหมด:
# Make sure globstar is enabled
shopt -s globstar
for i in **/*.txt; do # Whitespace-safe and recursive
process "$i"
done
ในบางกรณีเช่นถ้าชื่อไฟล์มีอยู่ในไฟล์คุณอาจต้องใช้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
การตั้งค่าตัวคั่นอย่างเหมาะสม:
find . -name '*.txt' -print0 |
while IFS= read -r -d '' line; do
process "$line"
done
สำหรับการค้นหาที่ซับซ้อนมากขึ้นคุณอาจต้องการใช้find
ด้วย-exec
ตัวเลือกหรือด้วย-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
ยังสามารถ cd ลงในไดเรกทอรีของแต่ละไฟล์ก่อนเรียกใช้คำสั่งโดยใช้-execdir
แทน-exec
และสามารถทำเป็นแบบโต้ตอบได้ (พร้อมท์ก่อนเรียกใช้คำสั่งสำหรับแต่ละไฟล์) โดยใช้-ok
แทน-exec
(หรือ-okdir
แทน-execdir
)
*: ตามหลักวิชาการทั้งสองfind
และxargs
(โดยค่าเริ่มต้น) จะเรียกใช้คำสั่งที่มีอาร์กิวเมนต์มากที่สุดเท่าที่พวกเขาสามารถใส่ในบรรทัดคำสั่งได้หลายครั้งเท่าที่จะสามารถผ่านไฟล์ทั้งหมดได้ ในทางปฏิบัติหากคุณไม่มีไฟล์จำนวนมากมันจะไม่สำคัญและถ้าคุณมีความยาวเกินกว่าที่กำหนด แต่ต้องการไฟล์ทั้งหมดในบรรทัดคำสั่งเดียวกันคุณก็จะหาวิธีที่แตกต่างกัน