BASH คัดลอกไฟล์ทั้งหมดยกเว้นไฟล์เดียว


111

ฉันต้องการคัดลอกไฟล์ทั้งหมดออกจาก dir ยกเว้นไฟล์ชื่อ Default.png ดูเหมือนว่ามีหลายวิธีในการทำเช่นนี้ อะไรที่ดูเหมือนจะมีประสิทธิภาพมากที่สุดสำหรับคุณ?


เหตุใดคุณจึงต้องข้ามไฟล์นั้นแทนที่จะลบทิ้งหลังจากคัดลอกแล้ว มีอยู่ในไดเร็กทอรีเป้าหมายแล้วหรือไม่?
Lasse V.Karlsen

1
ใช่ไฟล์ที่มีชื่อเดียวกันอยู่ในผบ. เป้าหมายแล้ว
Joe Cannatti

@ LasseV.Karlsen: หรือคุณอาจต้องการประหยัดเวลาในการคัดลอกหากเป็นไฟล์ขนาดใหญ่ ฉันสนใจสิ่งนี้ แต่ไม่รวมไดเร็กทอรีมากกว่าไฟล์
Nikana Reklawyks

คำตอบ:


54

ง่ายถ้าsrc/มีเฉพาะไฟล์:

find src/ ! -name Default.png -exec cp -t dest/ {} +

หากsrc/มีไดเร็กทอรีย่อยสิ่งนี้จะละเว้น แต่จะคัดลอกไฟล์ภายใน:

find src/ -type f ! -name Default.png -exec cp -t dest/ {} +

หากsrc/มีไดเร็กทอรีย่อยสิ่งนี้จะไม่เกิดขึ้นใหม่

find src/ -type f -maxdepth 1 ! -name Default.png -exec cp -t dest/ {} +

5
นี่เป็นสิ่งที่ดีที่สุดสำหรับฉันเพราะดูเหมือนว่า OS X จะจัดส่งโดยไม่เปิดใช้งาน glob
Joe Cannatti

6
@Max \;รันคำสั่งหนึ่งครั้งต่อไฟล์ +รันคำสั่งหนึ่งครั้งและส่งชื่อไฟล์ทั้งหมดไปพร้อมกัน (ขึ้นอยู่กับขีดจำกัดความยาวบรรทัดคำสั่ง) +โดยทั่วไปมีประสิทธิภาพมากกว่าเล็กน้อย
John Kugelman

150

ควรเป็นดังนี้:

cp -r !(Default.png) /dest

หากคัดลอกไปยังโฟลเดอร์ที่ซ้อนอยู่ในโฟลเดอร์ปัจจุบัน (เรียกว่าตัวอย่างในกรณีด้านล่าง) คุณต้องละเว้นไดเรกทอรีนั้นด้วย:

cp -r !(Default.png|example) /example

17
สิ่งนี้ก่อให้เกิด -bash:!: ไม่พบเหตุการณ์
Joe Cannatti

คุณกำลังคัดลอกไฟล์ไปยังโฟลเดอร์ที่ซ้อนอยู่ภายในโฟลเดอร์ที่คุณคัดลอกมาใช่หรือไม่
จอน

47
สิ่งนี้ต้องใช้shopt -s extglobงานได้หากถูกปิดใช้งาน
Barry Kelly

5
ดูเหมือนว่า OS X จำเป็นต้องใช้shopt -s extglobตามที่ @BarryKelly อธิบายไว้ ด้วยเหตุนี้จึงทำงานได้อย่างสมบูรณ์
กาด

ปีที่ Bash แล้วไม่รู้เรื่อง!()... สวย! สำหรับผู้ที่ --like me-- รู้สึกว่ามันเป็นเวลาที่จะศึกษา / ทบทวนทุบตีที่นี่มีความเกี่ยวข้องเชื่อมโยงที่เกี่ยวข้องกับคำถามนี้ / คำตอบ: shopt / extglobและรูปแบบ
Brandt

73

rsync เปลี่ยน cp / scp ของฉันมานานแล้ว:

rsync -av from/ to/ --exclude=Default.png

-a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose               increase verbosity

หากฉันต้องการแยกสองไฟล์ที่แตกต่างกันฉันจะใช้สิ่งนี้ได้อย่างไร
Pulkit Bansal

รองรับหลาย --exclude = อาร์กิวเมนต์ และอย่าลืม-rอาร์กิวเมนต์หากคุณกำลังซิงค์ไดเรกทอรี
Rian Sanderson

5

ฉันจะทำ:

cp srcdir/* destdir/ ; rm destdir/Default.png

เว้นแต่ไฟล์จะใหญ่ มิฉะนั้นให้ใช้เช่น

find srcdir -type f/ |grep -v Default.png$ |xargs -ILIST cp LIST destdir/

1
คำสั่งแรกไม่ใช่สิ่งที่ OP ขอ หากDefault.pngมีอยู่ในสองไดเรกทอรีก็จะเข้ามาแทนที่หนึ่งdestdirโดยหนึ่งในนั้นลบคัดลอกsrcdir Default.pngแต่ OP ต้องการที่จะเก็บที่มีอยู่แล้วในDefault.png destdir
SnowFrog

2
default.png มีอยู่แล้วใน destdir เป็นอย่างไร solutioun ของคุณจะไม่ทำงาน
Iman Mohamadi

2

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

   rsync -av fromDirectory/ ToDirectory/ --exclude=node_modules

1
cp `ls | grep -v Default.png` destdir

5
สิ่งนี้มีแนวโน้มที่จะทำให้เกิดข้อผิดพลาดมากกว่าการทำในสิ่งที่คุณตั้งใจ
หยุดชั่วคราวจนกว่าจะมีประกาศอีกครั้ง

สิ่งนี้ใช้ได้กับฉันบน Ubuntu 20.04
albertma789


-2

ใช้พารามิเตอร์การขยายของเชลล์กับ regex

cp /<path>/[^not_to_copy_file]* .

ทุกอย่างจะถูกคัดลอกยกเว้น not_to_copy_file

- หากมีสิ่งผิดปกติเกิดขึ้น กรุณาระบุ!


1
ยินดีต้อนรับสู่ SO ขออภัยคำตอบของคุณไม่ถูกต้อง การแสดงออกของวงเล็บ ( [...]) ประกอบด้วยชุดของอักขระที่จะจับคู่ในขณะที่นำหน้า^จะทำให้เกิดการจับคู่ของส่วนเติมเต็มของอักขระที่แสดง ในตัวอย่างต่อไปนี้ไฟล์จะไม่ได้รับการจดทะเบียน: touch not_to_copy_file to_copy_file ; ls [^not_to_copy_file]*เพราะทุกไฟล์ที่ขึ้นต้นด้วยตัวอักษรใด ๆ _cefilnoptyต่อไปนี้จะได้รับการยกเว้น:
rtx13
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.