อาร์กิวเมนต์ที่หายไปของ -exec คืออะไร


15

ฉันใช้คำสั่งต่อไปนี้เพื่อล้างไดเรกทอรีของไฟล์และไดเรกทอรีที่มีอายุมากกว่า 30 วันและย้ายไปยังไดเรกทอรีเก็บถาวรซึ่งฉันสามารถลบได้หลังจากสองสามสัปดาห์หากไม่มีใครขอไฟล์คืน ไดเรกทอรีเป้าหมายมีไดเรกทอรีย่อยตามชื่อผู้ใช้ดังนั้นไดเรกทอรีจะเก็บถาวร

นี่คือคำสั่งที่ฉันใช้:

find /path/to/directory/username/ -mtime +30 -exec mv "{}" /path/to/archive/username/ \;

ผมแนะนำรุ่นล่าสุดนี้จะตอบคำถามเกี่ยวกับการขอให้อูบุนตูผู้ใช้อื่นแก้ไขรหัสเพื่อเปลี่ยนจุดสิ้นสุดของบรรทัด\;สำหรับ+เป็นมันเร็วขึ้น (และอื่น ๆ ถูกต้องหรือไม่) ดูที่นี่

อย่างไรก็ตามการใช้ +วิธีนี้ใช้ได้ถ้า-execคำสั่งนั้นls -lhไม่ใช่ในคำสั่งจริงที่ฉันใช้ ถ้าฉันลองด้วย+ฉันได้รับข้อความแสดงข้อผิดพลาด:

find: missing argument to '-exec'

ฉันไม่เข้าใจว่าทำไมมันทำงานแบบนี้หรือคำสั่งที่ถูกต้องจะเป็นอย่างไร โปรดอย่าเพิ่งโพสต์การแก้ไขคำสั่งฉันต้องการเข้าใจมากกว่าเพียงแค่ทำตามคำแนะนำอย่างสุ่มสี่สุ่มห้า


คุณหมายถึงคำตอบนี้หรือไม่? สิ่งนี้อาจอธิบายได้ว่าทำไม
วิลฟ์

ขอบคุณ @ Wilf ฉันได้อัพเดทเพื่อแสดงคำตอบที่แก้ไขแล้ว ลิงค์ที่คุณให้ไว้มีลิงค์เพิ่มเติมซึ่งอธิบายในลักษณะที่สมองของฉันสามารถรับมือได้
Arronical


ขอบคุณ @souravc ในลักษณะวนรอบอย่างชาญฉลาดว่าคำถามคือโดยผู้ใช้ที่แก้ไขคำสั่งของฉัน! ในที่สุดฉันก็ได้รับมัน+ขัดแย้งหลายคำสั่งเดียวกัน แต่mvไม่สามารถรับมือกับที่!
Arronical

@Avronical mv can ดูคำตอบของฉัน ^^
วุ่นวาย

คำตอบ:


19

ผู้ใช้ในโพสต์นั้นอาจบอกว่า +เครื่องหมายที่ส่วนท้ายของ-execคำสั่งนั้นเร็วกว่า แต่ไม่ใช่สาเหตุ

ให้ถือว่าfindคำสั่งส่งคืนไฟล์ต่อไปนี้:

/path/to/file1
/path/to/file2
/path/to/file3

-execคำสั่งปกติ( -exec command {} \;) รันหนึ่งครั้งสำหรับแต่ละไฟล์ที่ตรงกัน ตัวอย่างเช่น:

find ... -exec mv {} /target/ \;

รัน:

mv /path/to/file1 /target/
mv /path/to/file2 /target/
mv /path/to/file3 /target/

หากคุณใช้+เครื่องหมาย ( -exec command {} +) คำสั่งจะถูกสร้างโดยการเพิ่มไฟล์ที่ตรงกันหลายไฟล์ในตอนท้ายของคำสั่ง ตัวอย่างเช่น:

find ... -exec mv -t /target/ {} +

รัน:

mv -t /target/ /path/to/file1 /path/to/file2 /path/to/file3

หากต้องการใช้การ+ตั้งค่าสถานะอย่างถูกต้องอาร์กิวเมนต์ในการดำเนินการจะต้องอยู่ท้ายคำสั่งไม่ใช่ตรงกลาง นั่นเป็นเหตุผลที่findtrows missing argument to '-exec'ในตัวอย่างของคุณ; {}คิดถึงปิด


ผมเคยสงสัยว่าทำไมfind -execต้องที่จะหาเรื่องที่ผ่านมาเมื่อใช้กับ{} +ใครรู้ว่าทำไมการตัดสินใจออกแบบนั้นแทนที่จะปล่อยให้โครงสร้างเหมือนคำสั่งของ OP ทำงาน
Peter Cordes

11

ผู้ใช้อธิบายการแก้ไขของพวกเขา ....

'+' จุดสิ้นสุดของ exec เร็วกว่า '\;'  ดู /ubuntu/558817/what-is-the-difference-between-using-and-in-exec-command;  และการสร้างไฟล์สำรองจากไฟล์ต้นฉบับเป็นความคิดที่ดี

... ใช้ลิงค์นี้ ฉันคิดว่าโดยทั่วไปแทนที่จะใช้หลายคำสั่งมันจะส่งชื่อไฟล์ทั้งหมดไปยังอินสแตนซ์คำสั่งเดียวเพื่อเร่งความเร็ว นี่คือตัวอย่างจากที่นี่ :

การใช้ -exec ด้วยเซมิโคลอน ( find . -exec ls '{}' \;) จะทำงาน

ls file1
ls file2
ls file3

แต่ถ้าคุณใช้เครื่องหมายบวกแทน ( find . -exec ls '{}' \+) ชื่อไฟล์ทั้งหมดจะถูกส่งผ่านเป็นอาร์กิวเมนต์ไปที่คำสั่งเดียว:

ls file1 file2 file3

มีรูปแบบอื่น ๆ ที่ใช้งาน;และ+เช่นกัน (จากที่นี่ :)

ดังนั้นไวยากรณ์ตัวอย่างต่อไปนี้ได้รับอนุญาตสำหรับคำสั่ง find:

find . -exec echo {} \;
find . -exec echo {} ';'
find . -exec echo {} ";"
find . -exec echo {} \+
find . -exec echo {} +

อย่างไรก็ตามฉันไม่แน่ใจว่าสิ่งนี้จะทำงานกับคำสั่งย้ายอย่างไรก็ตามเนื่องจากเป็นไวยากรณ์ mv [OPTION]... SOURCE DESTยกเว้นว่าใช้-tตัวเลือกหรือคล้ายกัน อย่างไรก็ตามควรทำงานโดยlsไม่มีตัวเลือกพิเศษอื่น ๆ เนื่องจากสามารถเข้าใจได้เมื่อมีการกำหนดชื่อไฟล์หลาย ๆ ไฟล์ +ยังอาจจะต้องหนี (เช่น\+)


ทั้งคำตอบที่ยอดเยี่ยม แต่ฉันต้องทำให้มันสับสนเพราะการเป็นบิตเร็วขึ้นและอธิบายmv -tทั้ง +1 ทั้งคู่!
Arronical
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.