ฉันสับสนว่าเหตุใดไดเรกทอรีที่ถูกตัดออกถูกพิมพ์โดยfindคำสั่งด้วยและรายละเอียดที่ซับซ้อนอื่น ๆ เกี่ยวกับวิธีการ-pruneทำงาน แต่ก็สามารถเข้าใจได้ด้วยตัวอย่างบางส่วน
หากต้องการเรียกใช้ตัวอย่างด้านล่างให้สร้างไดเรกทอรีและไฟล์ต่อไปนี้
mkdir aa
mkdir bb
touch file1
touch aa/file1
touch bb/file3
ในการสร้างโครงสร้างนี้:
$ tree
.
├── aa
│ └── file1
├── bb
│ └── file3
└── file1
aaตอนนี้ใช้หาที่จะมองหาไดเรกทอรีที่มีชื่อ ไม่มีปัญหาที่นี่
$ find . -type d -name aa
./aa
ค้นหาไดเรกทอรีทั้งหมดนอกเหนือจาก aa และเราได้รับไดเรกทอรีปัจจุบัน.และ./bbซึ่งก็สมเหตุสมผล
$ find . -type d ! -name aa
.
./bb
จนถึงตอนนี้ดีมาก แต่เมื่อเราใช้งาน-prunefind จะคืนค่าไดเรกทอรีที่เรากำลังตัดซึ่งตอนแรกทำให้ฉันสับสนเพราะฉันคาดว่ามันจะส่งคืนไดเรกทอรีอื่นทั้งหมดและไม่ใช่ไดเรกทอรีที่ถูกตัด
$ find . -type d -name aa -prune
./aa
เหตุผลที่ส่งคืนไดเร็กทอรีที่ถูกตัดจะไม่อธิบายใน-pruneส่วนของ man pages ดังที่ระบุไว้ในคำตอบของ Timoแต่ในEXPRESSIONSหัวข้อ:
หากการแสดงออกมีการกระทำอื่น ๆ กว่าไม่-prune,
-printจะดำเนินการเกี่ยวกับไฟล์ทั้งหมดที่แสดงออกเป็นความจริง
ซึ่งหมายความว่าเนื่องจากการแสดงออกที่ตรงกับaaชื่อไดเรกทอรีแล้วการแสดงออกจะประเมินเป็นจริงและมันจะถูกพิมพ์เพราะการค้นหาเพิ่มโดยปริยาย-printที่ท้ายคำสั่งทั้งหมด อย่างไรก็ตามจะไม่เพิ่มก-printหากคุณตั้งใจเพิ่มการกระทำ-o -printลงไปในตอนท้ายด้วยตนเอง:
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
ที่นี่คำสั่ง find ไม่เพิ่มความหมาย-printอีกต่อไปดังนั้นไดเรกทอรีที่เราตัด ( aa) จะไม่ถูกพิมพ์
ดังนั้นในที่สุดหากเราเพิ่มส่วนคำสั่งที่ค้นหาไฟล์ที่มีรูปแบบชื่อไฟล์file*หลังจาก-oนั้นคุณจะต้องวาง-printส่วนท้ายของส่วนคำสั่งที่สองดังนี้:
find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3
เหตุผลที่ทำให้การทำงานเหมือนกัน: ถ้าคุณไม่ใส่-printประโยคที่สองลงไปเนื่องจากไม่มีการกระทำใดนอกเหนือจาก-pruneการกระทำการค้นหาจะเพิ่ม-printคำสั่งโดยอัตโนมัติเมื่อสิ้นสุดคำสั่งทำให้-pruneคำสั่งพิมพ์ ไดเร็กทอรีที่ถูกตัดทิ้ง:
find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3
โดยทั่วไปคุณต้องวาง-printคำสั่งในประโยคที่สอง หากคุณวางไว้ตรงกลางเหมือนโปสเตอร์ต้นฉบับมันจะไม่ทำงานอย่างถูกต้องเพราะไฟล์ที่ถูกตัดจะถูกพิมพ์ทันทีและประโยคที่สองจะไม่ได้รับโอกาสในการเลือกไฟล์ที่ต้องการ:
find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3
น่าเสียดายที่โปสเตอร์ต้นฉบับนั้นได้รับคำสั่งที่ผิดด้านบนโดยการวาง-printในตำแหน่งที่ผิด อาจใช้กับกรณีเฉพาะของเขา แต่ไม่สามารถใช้งานได้ในกรณีทั่วไป
มีคนหลายพันคนที่มีปัญหาในการเข้าใจวิธีการ-pruneทำงาน findหน้าคนควรได้รับการปรับปรุงเพื่อป้องกันความสับสนทั่วโลก neverending เกี่ยวกับคำสั่งนี้
-printมิฉะนั้นนัย-printจะใช้กับเงื่อนไขทั้งหมด