สัญลักษณ์แทนไม่ทำงานในคำสั่ง cp เมื่อใช้ exec


3

ฉันต้องการคัดลอกไฟล์ทั้งหมดในไดเรกทอรีทั้งหมดไปยังไดเรกทอรีหลัก แต่ฉันได้รับข้อผิดพลาด

./img/* is not a directory

ตัวอย่างเช่น. นี่คือคำสั่งที่ฉันใช้ มีวิธีที่ดีกว่าในการทำเช่นนี้?

find . -type d -regex './[a-z]*' -exec cp -v {}/* .. \;

คำตอบ:


2

ลอง:

find . -type d -regex './[a-z]*' -exec bash -c 'cp -v "$1"/* ..' Cp {} \;

การสนทนา

พิจารณา:

find . -type d -regex './[a-z]*' -exec cp -v {}/* .. \;

เมื่อ bash เห็นบรรทัดนี้จะทำการขยายชื่อพา ธ {}/*. เนื่องจากมี (โดยทั่วไป) ไม่มีชื่อไดเรกทอรี {}, * เหลือเป็นตัวอักษร *. นี่ไม่ใช่สิ่งที่คุณต้องการ คุณต้องมีการขยายชื่อพา ธ หลังจาก find ได้แทนที่ในสำหรับ {}. โดยการวาง cp คำสั่งในเครื่องหมายคำพูดและส่งผ่านเป็นอาร์กิวเมนต์ bash -cเราบรรลุเป้าหมายนั้น

แบบฟอร์มตัวอย่างสำหรับ bash -c ดูเหมือนกับ:

bash -c 'code...' a b c 

สิ่งนี้บอกว่าทุบตีเพื่อมอบหมาย a ไปยัง $0, b ไปยัง $1, c ไปยัง $2 จากนั้นดำเนินการ code.... หากมีข้อผิดพลาดเกิดขึ้นเชลล์จะใช้ $0 เป็นชื่อของโปรแกรมที่กำลังดำเนินการ (ในข้อความข้อผิดพลาด) ด้านบนเราเลือก Cp เป็นชื่อที่สื่อความหมาย นอกจากนี้ข้างต้น {} ถูกแทนที่ด้วย $1 และเราใช้ประโยชน์ $1 ใน code.... เมื่อใช้วิธีนี้ {} ไม่จำเป็นต้องอ้าง (แต่มันไม่เจ็บถ้าคุณทำ); find จัดการกับการหลบหนีที่จำเป็น ภายใน code...อย่างไรก็ตาม $1 ควรอยู่ในเครื่องหมายคำพูดเพื่อป้องกันการแยกคำและการขยายชื่อ


ขอบคุณมาก! คุณช่วยอธิบายได้ไหมว่าทำไมตอนนี้ถึงใช้งานได้
m0meni

@ AR7 ฉันเพิ่งปรับปรุงคำตอบ แจ้งให้เราทราบหากช่วยได้
John1024

มันช่วยได้มาก คุณทำให้วันของฉัน
m0meni

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