`find` ด้วยหลาย` -name 'และ `-exec` รันเฉพาะการจับคู่สุดท้ายของ` -name'


74

เมื่อฉันใช้

find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt"

พบไฟล์ทุกประเภท แต่เมื่อฉันเพิ่ม-execในตอนท้าย:

find . -type f -name "*.htm*" -o -name "*.js*" -o -name "*.txt" -exec sh -c 'echo "$0"' {} \;

ดูเหมือนว่าจะพิมพ์.txtไฟล์เท่านั้น ผมทำอะไรผิดหรือเปล่า?

หมายเหตุ: ใช้ MINGW (Git Bash)


คำแนะนำ: คำสั่งแรกยังจะพิมพ์ไดเรกทอรีที่มีชื่อตรงกับหรือ*.js* *.txt
Wildcard

คำตอบ:


99
หา -type f -name "* .htm *" -o -name "* .js *" -o -name "* .txt"

สั้นสำหรับ:

หา \ (\ ( - ประเภท f -a -name "* .htm *" \) -o \
          \ (- ชื่อ "* .js *" \) -o \
          \ (- ชื่อ "* .txt" \) \
       \) -a- พิมพ์

นั่นคือเนื่องจากไม่ได้ระบุการกระทำของเพรดิเคต ( เงื่อนไขเท่านั้น) การ-printดำเนินการจะถูกเพิ่มโดยนัยสำหรับไฟล์ที่ตรงกับเงื่อนไข

(และโดยวิธีการที่จะพิมพ์.jsไฟล์ที่ไม่ปกติ( -type fเฉพาะ.htmไฟล์ที่ใช้))

ในขณะที่:

หา -type f -name "* .htm *" -o -name "* .js *" -o -name "* .txt" \
  -exec sh -c 'echo "$ 0"' {} \;

สั้นสำหรับ:

หา \ ( -type f -a- name "* .htm *" \) -o \
       \ (- ชื่อ "* .js *" \) -o \
       \ ( -name "* .txt" -a -exec sh -c 'echo "$ 0"' {} \; \)

สำหรับfind(เช่นในหลายภาษา) และ ( -aโดยปริยายเมื่อละเว้น) มีความสำคัญมากกว่าOR ( -o) และการเพิ่มคำกริยาการกระทำที่ชัดเจน (ที่นี่-exec) ยกเลิกการ-printกระทำโดยนัยที่เห็นด้านบน ที่นี่คุณต้องการ:

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) \
  -exec sh -c 'echo "$0"' {} \;

หรือ:

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -exec sh -c '
   for i do
     echo "$i"
   done' sh {} +

เพื่อหลีกเลี่ยงการรันหนึ่งshไฟล์ต่อหนึ่งไฟล์


ในบางส่วนของการใช้ sh -c คุณต้องเพิ่มอาร์กิวเมนต์ zeroth สำหรับ sh (แต่ในที่อื่น ๆ คุณรวมไว้แล้ว)
James Youngman

1
นั่นเป็นคำตอบที่ยอดเยี่ยม!
Marinos

30

มันคือวงเล็บเหลี่ยม เพิ่มวงเล็บอย่างชัดเจน\( \)

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -exec sh -c 'echo "$0"' {} \;

หรือใช้ xargs (ฉันชอบ xargs ฉันพบว่าง่ายกว่า แต่เห็นได้ชัดว่าไม่ใช่พกพา)

find . -type f \( -name "*.htm*" -o -name "*.js*" -o -name "*.txt" \) -print0 | xargs -0 -n1 echo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.