วิธีการใช้ `find -exec` เพื่อเรียกใช้งานคำสั่งในไดเรกทอรีของไฟล์ที่พบ (ไม่ใช่ไดเรกทอรีปัจจุบัน)?


15

สมมติว่าผมอยู่ในไดเรกทอรีที่มีไดเรกทอรีย่อยบางdir1, และdir2 dir3แต่ละไดเรกทอรีเหล่านี้มีไฟล์fooและฉันต้องการที่จะดำเนินการคำสั่งเดียวกันfooในแต่ละไดเรกทอรีและมีคำสั่งที่ดำเนินการจากภายในไดเรกทอรีนั้น

ถ้าฉันจะทำ "ด้วยมือ" มันจะมีลักษณะเช่นนี้:

cd dir1
(execute on foo)
cd ../dir2
(execute on foo)
cd ../dir3
(execute on foo)

มันเป็นความจำเป็นที่คำสั่งจะดำเนินการจากแต่ละไดเรกทอรี fooเป็นสคริปต์การตั้งเวลาแบทช์ (สำหรับ HTCondor หากคุณต้องการทราบ) และจะต้องดำเนินการจากแต่ละไดเรกทอรีย่อยเพื่อให้ผลลัพธ์ของการดำเนินการเริ่มต้นโดยสคริปต์การตั้งเวลาจะสิ้นสุดในแต่ละไดเรกทอรีย่อย

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


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

คำตอบ:


23

สมมติว่าคุณfindสนับสนุนให้ใช้-execdirตัวเลือกแทน-exec

find * -name 'foo' -execdir pwd \;

หากไม่มีโปรดระบุรายละเอียดของแพลตฟอร์มและ / หรือการกระจายของคุณ (ตามความเหมาะสม)


เมื่อคุณเริ่มกดปุ่ม "ค้นหา: พา ธ สัมพัทธ์ './node_modules/.bin' รวมอยู่ในตัวแปรสภาพแวดล้อม PATH": askubuntu.com/questions/621132/ …
Ciro Santilli 冠状病毒审查审查六四法轮功事件

ขออภัยถ้าผมอาจจะเขียนมันเหมือนว่า แต่ -execdir (บน Ubuntu) เป็นอึเพราะมันไม่ได้ให้คุณแต่แม่ของ{} {}
uav

1
@uav โดยไม่ทราบว่ากรณีการใช้งานของคุณฉันไม่สามารถช่วยคุณได้ แต่ในการตอบสนองต่อความต้องการของคุณเอกสารระบุอย่างชัดเจนว่า " ถูกใจ-execแต่คำสั่งที่ระบุจะถูกเรียกใช้จากไดเรกทอรีย่อยที่มีไฟล์ที่ตรงกัน "
roaima

ใช่ถูกต้องมันเป็นกรณีพิเศษหากคุณกำลังมองหา -type d (= ไดเรกทอรี) จากนั้นจึงเป็นแบบย่อยที่ดีที่สุด
uav

กรณีที่คุณไม่ทราบว่าใช้งานอย่างไรฉันไม่สามารถช่วยคุณได้
roaima

4

สมมติว่าคุณรู้ว่าไดเรกทอรีใดที่จะเรียกใช้คำสั่งของคุณ

for dir in dir1 dir2 dir3; do
    ( cd "$dir" && somecommand foo )
done

หรือวนลูปมากกว่าfooไฟล์

for foo in */foo; do
  ( cd "${foo%/*}" && somecommand foo )
done

เชลล์ย่อยป้องกันไม่cdให้มีผลกับไดเร็กทอรีการทำงานของสคริปต์ที่เหลือ ${foo%/*}เปลี่ยนตัวพารามิเตอร์ขยายไปยังชื่อของไดเรกทอรีที่fooชีวิตของไฟล์ (โดยการเอาทุกอย่างหลังจากสุดท้าย/ในค่าของ$foo)

การใช้มาตรฐานfindเพื่อทำสิ่งเดียวกัน (ในกรณีที่fooไฟล์อาจอยู่ลึกลงไปในโครงสร้างไดเรกทอรี):

find . -type f -name foo -exec sh -c '
    for foo do
        ( cd "${foo%/*}" && somecommand foo )
    done' sh {} +

ในคำ: ค้นหาไฟล์ปกติทั้งหมดที่เรียกว่า "foo" ที่ใดก็ได้ในไดเรกทอรีปัจจุบันหรือด้านล่างและให้ชื่อพา ธ ของพวกเขากับเชลล์สคริปต์นี้เป็นแบทช์ สคริปต์เปลือกจะย้ำกว่า pathnames กำหนดไดเรกทอรีการเปลี่ยนแปลงในส่วนของแต่ละไดเรกทอรีชื่อพา ธ somecommand fooและหากที่ประสบความสำเร็จการดำเนินการ

สำหรับการแก้ปัญหาที่ใช้เป็นมาตรฐานที่-execdirให้ดูคำตอบของ roaima คำตอบของเขาปรับให้เข้ากับตัวอย่างของฉัน:

find . -type f -name foo -execdir somecommand foo ';'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.