Linux: คัดลอกไฟล์ทั้งหมดที่ตรงกับรูปแบบจาก dir และส่วนย่อยลงใน dir เดียว


31

หากฉันต้องการคัดลอก*.soไฟล์ทั้งหมดจากsrcไปยังdstฉันจะทำ:

cp src/*.so dst

แต่ผมต้องการที่จะคัดลอก*.soไฟล์จาก src และมันเป็น subdirsdstเข้า เบาะแสใด ๆ

คำตอบ:


36

ลอง:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

17
findสามารถจับคู่รูปแบบและรันคำสั่งได้ ไม่จำเป็นต้องมีท่อไม่มีเอาท์พุท:find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'
jáquer

1
ใช่มันสามารถ แต่ก็มักจะง่ายต่อการอ่านท่อยังความสามารถในการจับคู่รูปแบบของgrepไกลเกินดุลรูปแบบเปลือกเรียบง่ายใช้ในพารามิเตอร์ -name นอกจากนี้ยังห่างไกลที่มีประสิทธิภาพมากขึ้นกว่าพารามิเตอร์ findxargs-execfind
Mike Insch

2
วิธีแก้ปัญหาของ @jaquer นั้นดีกว่าเพราะในอรรถประโยชน์ของ MacOSX xargs ไม่มีตัวเลือก -i แต่ทางออกของเขาทำงานได้อย่างมีเสน่ห์
bialix

ฉันกำลังดิ้นรนกับข้อความแสดงข้อผิดพลาดในอาร์กิวเมนต์ -i ถึง xargs จนกระทั่งฉันอ่านความคิดเห็นจาก @bialix เกี่ยวกับโซลูชันของ jaquer ซึ่งทำงานได้ดีบน Mac ของฉัน ขอบคุณ
svannoy

สิ่งนี้จะสร้างไดเรกทอรีย่อยตามต้องการหรือไม่
Lennart Rolland

15

หากคุณใช้ Bash คุณสามารถเปิดglobstar ตัวเลือกเชลล์เพื่อจับคู่ไฟล์และไดเรกทอรีซ้ำ:

shopt -s globstar
cp src/**/*.so dst

หากคุณต้องการค้นหาไฟล์ที่ชื่อขึ้นต้นด้วย.และ / หรือไฟล์ในและภายใต้ไดเรกทอรีที่ชื่อขึ้นต้น.ให้ตั้งค่าdotglobตัวเลือกด้วย (เช่นกับshopt -s dotglob) คุณสามารถตั้งค่าได้ทั้งสองในคำสั่งเดียว:

shopt -s globstar dotglob

ห้ามคัดลอกไฟล์ในไดเรกทอรีย่อยที่ขึ้นต้นด้วย a ในชื่อของพวกเขา
rboy

8

ฉันลองคำสั่งที่ Mike แนะนำ:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

แต่มันจบลงด้วยการทิ้งไฟล์ทั้งหมดลงในไดเรกทอรีที่dstมีเส้นทางญาติของพวกเขาหายไป

ในการเก็บพา ธ สัมพัทธ์คำสั่งจะต้องมีการแก้ไขในสิ่งนี้:

find src/ -type f | grep -i so$ | xargs -i cp {} dst/{}

7
+1 dstแต่นี้อนุมานว่าไดเรกทอรีที่สอดคล้องกับเส้นทางแหล่งญาติอยู่ภายใต้ cp --parentsในกรณีที่ไม่ได้เป็นเช่นนั้นการใช้งาน นอกจากนี้อย่าลืมอ้างชื่อไฟล์ ดังนั้น: ... | xargs -i cp --parents "{}" dst(โปรดทราบว่าอาร์กิวเมนต์สุดท้ายที่cpเป็นตอนนี้ "เพียงแค่" ไดเรกทอรีปลายทาง) คำสั่งที่สามารถทำแม้สั้น (และอาจจะเร็วกว่า) โดยใช้ธง:-t ... | xargs cp --parents -t dst
Stephan202

1
@ Stephan202 ฉันต้องใช้... | xargs cp {} --parents -t dst.
warvariuc

สำหรับผู้ที่ใช้ mac --parentsไม่สามารถใช้งานได้ ฉันใช้dittoแทน: stackoverflow.com/questions/11246070/cp-parents-option-on-mac
Bryan Young

3

อีกวิธีในการทำเช่นนี้คือ:

find src/ -type f -name "*.so" -exec cp {} dst/ \;

และควรลดจำนวนของกระบวนการ:cp ... -exec cp -t dst/ {} +
Kamil Maciorowski

เฮ้คามิล! ขอบคุณสำหรับความคิดเห็น! คุณช่วยอธิบายวิธีแก้ปัญหาของคุณให้เร็วขึ้นได้ไหม! ยินดีที่จะเรียนรู้เพิ่มเติมเสมอ :)
Kyriakos

เมื่อคุณจบ-execด้วย;, {}จะถูกแทนที่โดยเส้นทางในช่วงเวลาหนึ่ง คุณได้รับแยกต่างหากcpสำหรับทุกไฟล์ ด้วย+ไวยากรณ์findจะแทนที่{}ด้วยผลลัพธ์หลายรายการ (สูงสุดถึงขีด จำกัด ที่ระบบกำหนดของความยาวบรรทัดคำสั่งการ จำกัด : {}ต้องเป็นสิ่งสุดท้ายก่อน+ดังนั้นcp -t) การสร้างและการยกเลิกโปรเซสนั้นค่อนข้างแพง ด้วยเหตุนี้จึงเป็นการดีที่จะใช้+เมื่อใดก็ตามที่คุณคาดหวังผลลัพธ์จำนวนมาก ในกรณีนี้การคัดลอกไฟล์จำนวนมากอาจใช้เวลานานดังนั้นความแตกต่างอาจไม่มีการสังเกต อย่างไรก็ตามมันเป็นการปฏิบัติที่ดี
Kamil Maciorowski

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