ฉันสับสนว่าเหตุใดไดเรกทอรีที่ถูกตัดออกถูกพิมพ์โดย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
จนถึงตอนนี้ดีมาก แต่เมื่อเราใช้งาน-prune
find จะคืนค่าไดเรกทอรีที่เรากำลังตัดซึ่งตอนแรกทำให้ฉันสับสนเพราะฉันคาดว่ามันจะส่งคืนไดเรกทอรีอื่นทั้งหมดและไม่ใช่ไดเรกทอรีที่ถูกตัด
$ 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
จะใช้กับเงื่อนไขทั้งหมด