คำตอบของ muruนั้นเหมาะสมและเหมาะสมกับกรณีที่เราต้องการพิมพ์บางอย่างหากพบไฟล์ สำหรับกรณีทั่วไปเมื่อเราต้องการรันคำสั่งภายนอกเช่นechoเราสามารถใช้การ-execตั้งค่าสถานะ
$ find . -name 'xac' -exec echo "I found " {} \; -quit
I found ./xac
{}ส่วนหนึ่งผ่านชื่อไฟล์คำสั่งระหว่าง-execและ\;เป็นข้อโต้แย้ง หมายเหตุ\ก่อน;- ป้องกันไม่ให้มันจากเปลือกตีความมันในการปิดเปลือกหมายอัฒภาคปลายคำสั่ง แต่เมื่อหนีออกมาด้วยการเฉือนเปลือกจะรักษามันเป็นข้อความ literall จะถูกส่งผ่านไปยังfindคำสั่งและคำสั่งที่จะหามันทำหน้าที่เป็นปิด-execการขัดแย้งธง
สำหรับการสร้าง conditionals ของif found do this; else do thatsort เราสามารถใช้ประโยชน์จาก substition คำสั่ง$()และtestcommand (aka [):
$ [ "x$(find . -name 'noexist' -print -quit)" != "x" ] && echo "found" || echo "not found"
not found
$ [ "x$(find . -name 'xac' -print -quit)" != "x" ] && echo "found" || echo "not found"
found
พูดถึงความคิดเห็นของแดน
แดนในความคิดเห็นที่ถาม:
จะไม่สะท้อน "ฉันพบ {}" ดีกว่าเสียงสะท้อน "ฉันพบ" {} หรือไม่ อาจเป็นเพราะเสียงสะท้อนได้ดี แต่ถ้ามีคนคัดลอกคำสั่งและแทนที่เสียงสะท้อนด้วยคำสั่งอื่นพวกเขาอาจมีปัญหา
มาทำความเข้าใจปัญหาก่อนกัน โดยปกติแล้วใน shells จะมีแนวคิดเกี่ยวกับการแบ่งคำซึ่งหมายถึงตัวแปรที่ไม่ได้กล่าวถึงและพารามิเตอร์ตำแหน่งจะถูกขยายและถือเป็นรายการแยกต่างหาก ตัวอย่างเช่นถ้าคุณมีตัวแปรvarและจะมีhello worldข้อความเมื่อคุณทำtouch $varเชลล์จะทำลายมันลงเป็นสองรายการแยกต่างหากhelloและworldและtouchจะเข้าใจว่าราวกับว่าคุณกำลังพยายามที่จะสร้าง 2 ไฟล์แยกเป็นสัดส่วน ถ้าคุณทำtouch "$var"แล้วเปลือกจะถือว่าhello worldเป็นหนึ่งหน่วยและtouchจะสร้างหนึ่งไฟล์เท่านั้น สิ่งสำคัญคือต้องเข้าใจว่าสิ่งนี้เกิดขึ้นเพียงเพราะเปลือกทำงานอย่างไร
ในทางตรงกันข้ามfindจะไม่ประสบกับพฤติกรรมดังกล่าวเนื่องจากคำสั่งถูกประมวลผลด้วยfindตัวเองและดำเนินการโดยการexecvp()เรียกของระบบดังนั้นจึงไม่มีเชลล์ที่เกี่ยวข้อง ในขณะที่เครื่องหมายปีกกามีความหมายพิเศษในกระสุนเพราะมันปรากฏอยู่ตรงกลางของfindคำสั่งและไม่ใช่จุดเริ่มต้นพวกเขาไม่มีความหมายพิเศษกับกระสุนในกรณีนี้ นี่คือตัวอย่าง ลองสร้างชื่อไฟล์ที่ยากขึ้นมาหน่อยและลองส่งมันเป็นอาร์กิวเมนต์เพื่อstatสั่ง
$ touch with$'\t'tab.txt with$' 'space.txt with$'\n'newline.txt
$ find -type f -exec stat -c "%F" {} \; -print
regular empty file
./with?newline.txt
regular empty file
./with space.txt
regular empty file
./with?tab.txt
ดังที่คุณเห็นstatได้รับชื่อไฟล์ยากfindๆ ซึ่งเป็นหนึ่งในเหตุผลหลักที่แนะนำให้ใช้ในสคริปต์แบบพกพาและมีประโยชน์อย่างยิ่งเมื่อคุณสำรวจทรีไดเรกทอรีและต้องการทำบางสิ่งบางอย่างกับชื่อไฟล์ที่อาจมี ตัวอักษรพิเศษในพวกเขา findดังนั้นจึงไม่จำเป็นที่จะพูดวงเล็บปีกกาสำหรับคำสั่งดำเนินการใน
มันเป็นเรื่องที่แตกต่างเมื่อกระสุนเข้ามาเกี่ยวข้อง บางครั้งคุณต้องใช้เชลล์เพื่อประมวลผลชื่อไฟล์ ในกรณีนั้นการอ้างอิงจะมีความสำคัญ แต่สิ่งสำคัญคือต้องตระหนักว่าไม่ใช่ปัญหาของการค้นหา - เป็นเชลล์ที่แยกคำออก
$ find -type f -exec bash -c "stat {}" sh \;
stat: cannot stat './with': No such file or directory
sh: line 1: newline.txt: command not found
stat: cannot stat './with': No such file or directory
stat: cannot stat 'space.txt': No such file or directory
stat: cannot stat './with': No such file or directory
stat: cannot stat 'tab.txt': No such file or directory
ดังนั้นเมื่อเราเสนอราคาภายในเชลล์มันจะทำงานได้ findแต่อีกครั้งว่าเป็นสิ่งสำคัญสำหรับเปลือกไม่
$ find -type f -exec bash -c "stat -c '%F' '{}'" sh \;
regular empty file
regular empty file
regular empty file
/some/pathบอกให้ค้นหาว่าจะเริ่มมองที่ใด แต่ไม่มีอะไรบอกได้ว่าจะมองหาอะไร เหมือนกันในคำตอบที่เชื่อมโยงของคุณfind /some/path -name xac -print0 -quit | grep -qz . && echo foundสิ่งที่ไม่ทำงานสำหรับฉันก็คือ ฉันพลาดอะไรไปหรือเปล่า?