คัดลอกไฟล์ทั้งหมดที่มีนามสกุลที่แน่นอนจากไดเรกทอรีย่อยทั้งหมด


115

ภายใต้ unix ฉันต้องการคัดลอกไฟล์ทั้งหมดที่มีนามสกุล (ไฟล์ excel ทั้งหมด) จากไดเรกทอรีย่อยทั้งหมดไปยังไดเร็กทอรีอื่น ฉันมีคำสั่งต่อไปนี้:

cp --parents `find -name \*.xls*` /target_directory/

ปัญหาเกี่ยวกับคำสั่งนี้คือ:

  • มันคัดลอกโครงสร้างไดเร็กทอรีด้วยและฉันต้องการไฟล์เท่านั้น (ดังนั้นไฟล์ทั้งหมดควรลงท้ายด้วย / target_directory /)

  • ไม่คัดลอกไฟล์ที่มีช่องว่างในชื่อไฟล์ (ซึ่งค่อนข้างน้อย)

วิธีแก้ปัญหาเหล่านี้หรือไม่?


เกี่ยวกับอะไรfind... exec mv?
fedorqui 'SO หยุดทำร้าย'

คำตอบ:


178

--parents กำลังคัดลอกโครงสร้างไดเร็กทอรีดังนั้นคุณควรกำจัดสิ่งนั้น

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

$ find . -name \*.xls -exec cp {} newDir \;

ซึ่งcpดำเนินการสำหรับชื่อไฟล์แต่ละชื่อที่findค้นหาและส่งผ่านชื่อไฟล์อย่างถูกต้อง นี่คือข้อมูลเพิ่มเติมเกี่ยวกับเทคนิคนี้

แทนที่จะใช้ทั้งหมดข้างต้นคุณสามารถใช้zshและพิมพ์

$ cp **/*.xls target_directory

zsh สามารถขยายอักขระตัวแทนเพื่อรวมไดเรกทอรีย่อยและทำให้สิ่งนี้ง่ายมาก


2
ใช่. 'bin it' หมายถึงการทิ้งมันไป แก้ไขแล้ว :-)
Brian Agnew

13
Bash4.0 ขึ้นไปและนอกจากนี้ยังสนับสนุนksh93 **สำหรับ bash ให้ใช้shopt -s globstarเพื่อเปิดใช้งาน สำหรับ ksh มันคือset -Gหรือset -o globstar.
pynexj

5
ผู้บริหารนั้นมีประสิทธิภาพทางเทคนิคน้อยกว่าการส่งผ่านเข้าไปใน xargs ซึ่งจะทำทุกอย่างด้วยการเรียก cp ให้น้อยที่สุด: find . -name '*.xls' -print0 | xargs -0 cp -t destdir
Taywee

1
@Taywee - ครับ อย่างไรก็ตามฉันไม่ต้องการสร้างความสับสนให้กับประเด็นใด ๆ และมุ่งเน้นไปที่ปัญหานั้น ๆ การวัดประสิทธิภาพเพิ่มเติมเป็นสิ่งที่ดีเสมอ
Brian Agnew

2
@BrianAgnew โอ้ฉันแน่ใจว่าเพียงแค่มีข้อมูลเพิ่มเติมในความคิดเห็นสำหรับชาว Google ที่เอาแต่ใจ
Taywee

38

จากที่กล่าวมาทั้งหมดฉันได้สร้างเวอร์ชันนี้ขึ้นมา เวอร์ชันนี้ใช้ได้กับฉันในเทอร์มินัลการกู้คืน mac

find ./ -name '*.xsl' -exec cp -prv '{}' '/path/to/targetDir/' ';'

มันจะดูในไดเรกทอรีปัจจุบันและเรียกซ้ำในไดเรกทอรีย่อยทั้งหมดสำหรับไฟล์ที่มีนามสกุล xsl มันจะคัดลอกทั้งหมดไปยังไดเร็กทอรีเป้าหมาย

cp แฟล็กคือ:

  • p - รักษาคุณสมบัติของไฟล์
  • r - เรียกซ้ำ
  • v - verbose (แสดงให้คุณเห็นว่ากำลังคัดลอกอะไร)

1
นี่เหมือนกับสิ่งที่ฉันต้องทำเมื่อ SSH เข้าสู่ Bluehost
พลัมเมอร์

5
มันไม่ได้ดำรงตำแหน่งย่อย
b005t3r

3
@ b005t3r นั่นคือการออกแบบมันไม่ควร นั่นคือเจตนาทั้งหมดของคำถามของ OP เขาต้องการให้ไฟล์ทั้งหมดจากไดเรกทอรีย่อยคัดลอกไปยังไดเร็กทอรีเดียวโดยไม่มีไดเร็กทอรีย่อย
Madivad

3
มีวิธีแก้ไขสิ่งนี้เพื่อรักษาไดเรกทอรีย่อยหรือไม่?
Matthew Dean

@MatthewDean คุณสามารถใช้--parentsธงcpเพื่อทำสิ่งนั้นให้สำเร็จ บางอย่างเช่นfind ./ -name '*.xsl' -exec cp --parents {} targetDir/ ';'
drmercer

8

ฉันมีปัญหาที่คล้ายกัน ฉันแก้ไขโดยใช้:

find dir_name '*.mp3' -exec cp -vuni '{}' "../dest_dir" ";"

'{}'และ";"ดำเนินการคัดลอกในแต่ละไฟล์



1
find [SOURCEPATH] -type f -name '[PATTERN]' | 
    while read P; do cp --parents "$P" [DEST]; done

คุณสามารถลบ --parents ได้ แต่มีความเสี่ยงที่จะเกิดความขัดแย้งกันหากไฟล์หลายไฟล์มีชื่อเดียวกัน

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