ฉันต้องการค้นหาไดเรกทอรีทั้งหมดด้วยสตริงที่ระบุเพื่อให้ฉันสามารถค้นหาอื่นในไฟล์ที่อยู่ภายใน
ดังนั้นฉันไม่ต้องการเสียเวลากับ./my-search-term/dir/my-search-term
ฯลฯ
ฉันจะหยุดการเรียกซ้ำเมื่อฉันพบไดเรกทอรีของฉันคำค้นหาแรกได้อย่างไร
ฉันต้องการค้นหาไดเรกทอรีทั้งหมดด้วยสตริงที่ระบุเพื่อให้ฉันสามารถค้นหาอื่นในไฟล์ที่อยู่ภายใน
ดังนั้นฉันไม่ต้องการเสียเวลากับ./my-search-term/dir/my-search-term
ฯลฯ
ฉันจะหยุดการเรียกซ้ำเมื่อฉันพบไดเรกทอรีของฉันคำค้นหาแรกได้อย่างไร
คำตอบ:
การ-prune
ดำเนินการจะfind
ไม่ถูกเรียกคืนไปยังไดเรกทอรี คุณสามารถรวมเข้ากับการกระทำอื่นเช่น-exec
(ลำดับ-prune
และ-exec
ไม่สำคัญตราบใดที่-prune
มีการดำเนินการด้วยวิธีใดวิธีหนึ่ง)
find . -name my-search-term -prune -exec find {} … \;
โปรดทราบว่าการทำรังfind
อยู่ภายในfind -exec
อาจจะเป็นปัญหาเล็ก ๆ น้อย ๆ : คุณไม่สามารถใช้-exec
ในด้านเพราะเทอร์มิจะถูกมองว่าเป็นเทอร์มิจากด้านนอกได้find
find
คุณสามารถหลีกเลี่ยงปัญหานี้ได้ด้วยการเรียกใช้เชลล์ แต่ระวังการอ้างอิง
find . -name my-search-term -prune -exec sh -c '
find "$@" … -exec … {\} +
' _ {} +
-prune
ผลตอบแทนที่แท้จริง-exec
และสามารถใส่ก่อน
-o
ในนั้นฉันเดา และฉันเดาว่าการวาง-prune
ก่อนหน้า-exec
นั้นสามารถอ่านได้มากขึ้น
-prune
ตัวเลือกก่อนหน้านี้
mkdir -p x1 x2; touch x1/x11 x1/x12 x2/x21 x2/x22; find . -name 'x1*' -exec rm -rf {} \;
find: ./x1: No such file or directory
การแก้ปัญหาคือการเพิ่ม-prune
ในตอนท้ายของfind
คำสั่ง
find
ขยาย{}
แม้เมื่อมันปรากฏเป็น substring -exec
ของการโต้แย้งไปยัง รุ่นดังกล่าวของfind
จะสำลักคำสั่งที่สองของคุณเพราะ{}
ในด้านfind
คำสั่ง (ในคำสั่ง shell) find
จะถูกแทนที่ด้วยชื่อของไดเรกทอรีที่พบในด้านนอก คุณสามารถแก้ไขปัญหาด้วยการพูดว่าfind . -name my-search-term -prune -exec sh -c 'find "$0" … -exec … "{"} +' {} \;
คือใช้ซึ่งเปลือกจะเปลี่ยนเป็น"{"}
{}
... (ต่อ)
หากคุณต้องการfind
ข้ามเนื้อหาของไดเรกทอรีที่พบ แต่ค้นหาในไดเรกทอรีอื่นต่อให้ใช้-prune
@laebshade ที่แนะนำ คำสั่งแบบเต็มควรมีลักษณะเช่นนั้น
find . -type d -name somename -prune -exec ...
ในทางกลับกันถ้าคุณต้องการfind
ที่จะทั้งหมดหยุดการค้นหาและหลังจากการค้นหาไดเรกทอรีจับคู่แรกแล้วสิ่งที่คุณกำลังมองหาอยู่-quit
(ใช้ได้ตั้งแต่รุ่น4.2.3
ของGNU find
) อันนี้ค่อนข้างยุ่งยากกว่าที่จะใช้เพราะทำให้find
ออกทันที - ดังนั้น-quit
ต้องวางที่ส่วนท้ายสุดของคำสั่ง:
find . -type d -name somename -exec ... -quit
เพื่อให้การทำงานเป็นไปตามที่คาดไว้เราต้องรับรองว่า-exec
ผลตอบแทนที่แท้จริง (ในคำอื่น ๆ คือสถานะเป็นศูนย์ ) หากคุณต้องการให้สถานะการออก-exec
ถูกเพิกเฉยเพื่อให้ใช้-quit
งานได้ตลอดเวลาคุณต้องมีเคล็ดลับเล็กน้อย:
find . -type d -name somename \( -exec ... -o -true \) -quit
หรือ
find . -type d -name somename \( -exec ... -o -quit \)
หรือ
find . -type d -name somename \( -exec ... , -quit \) # a comma before -quit
สิ่งที่สำคัญที่สุดเกี่ยวกับวิธีการfind
ทำงานคือการกระทำทั้งหมด("การทดสอบ")ได้รับการปฏิบัติเหมือนภาคตรรกะตีความจากซ้ายไปขวา ดังนั้นการดำเนินการที่ผ่านมา (ตัวอย่าง-quit
) จะได้รับการดำเนินการหากส่วนที่ก่อนหน้านี้ทั้งหมดไม่ได้กลับเท็จ โดยค่าเริ่มต้นการทดสอบทั้งหมดจะถูกรวมเข้ากับตรรกะ "AND" -o
ตัวเลือกจะเปลี่ยนการเชื่อมต่อเป็น "OR"
องค์ประกอบที่ซับซ้อนของ-o
คือfind
สามารถ "เพิ่มประสิทธิภาพ" คำสั่งของคุณและไม่เรียกใช้-exec
ส่วนถ้าคุณพิมพ์เพียง
find . -type d -name somename -exec ... -o -quit
เพื่อรับมือกับสิ่งนั้นคุณสามารถบังคับfind
ให้ประเมินเพรดิเคตทั้งหมดที่มี "OR" โดยใส่ไว้ในวงเล็บ