BASH menyalin semua file kecuali satu

110

Saya ingin menyalin semua file dari sebuah dir kecuali yang bernama Default.png. Tampaknya ada beberapa cara untuk melakukan ini. Apa yang menurut Anda paling efektif?

Joe Cannatti
sumber
Mengapa Anda membutuhkannya untuk melewati file itu, bukan hanya menghapusnya setelah menyalinnya? Apakah sudah ada di direktori target?
Lasse V. Karlsen
1
Ya, file dengan nama yang sama sudah ada di direktori target.
Joe Cannatti
@ LasseV.Karlsen: Atau Anda mungkin ingin menghemat waktu untuk menyalinnya, jika itu file besar. Saya tertarik dengan ini tetapi tidak termasuk direktori daripada file.
Nikana Reklawyks

Jawaban:

54

Sederhana, jika src/hanya berisi file:

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

Jika src/memiliki sub-direktori, ini menghilangkannya, tetapi menyalin file di dalamnya:

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

Jika src/memiliki sub-direktori, ini tidak akan muncul kembali di dalamnya:

find src/ -type f -maxdepth 1 ! -name Default.png -exec cp -t dest/ {} +
John Kugelman
sumber
5
Ini ternyata menjadi yang terbaik bagi saya karena OS X akan tampak dikirimkan tanpa mengaktifkan glob.
Joe Cannatti
6
@Max \;menjalankan perintah satu kali per file. +menjalankan perintah satu kali dan meneruskan semua nama file sekaligus (tunduk pada batas panjang baris perintah). +sedikit lebih efisien secara umum.
John Kugelman
149

Seharusnya sebagai berikut:

cp -r !(Default.png) /dest

Jika menyalin ke folder yang bersarang di folder saat ini (disebut contoh dalam kasus di bawah), Anda juga perlu menghilangkan direktori itu:

cp -r !(Default.png|example) /example
Jon
sumber
17
Ini menghasilkan -bash:!: Acara tidak ditemukan
Joe Cannatti
Apakah Anda menyalin file ke folder bersarang di dalam folder tempat Anda menyalin?
Jon
47
Ini perlu shopt -s extglobbekerja, jika telah dinonaktifkan.
Barry Kelly
5
Sepertinya OS X perlu digunakan shopt -s extglobseperti yang dijelaskan oleh @BarryKelly. Dengan itu, ini bekerja dengan sempurna.
Kat
Bertahun-tahun di Bash dan tidak tahu tentang !()... Indah! Bagi mereka yang --seperti saya-- merasa sudah waktunya mempelajari / mengulas bash , berikut adalah tautan relevan yang terkait dengan pertanyaan / jawaban ini: shopt / extglob dan polanya .
Brandt
73

rsync telah menjadi pengganti cp / scp saya untuk waktu yang lama:

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

-a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose               increase verbosity
matja
sumber
Jika saya ingin mengecualikan dua file yang berbeda, bagaimana cara menggunakan ini?
Pulkit Bansal
beberapa argumen --exclude = didukung. Dan jangan lupa -rargumen jika Anda menyinkronkan direktori
Rian Sanderson
5

Saya hanya akan melakukan:

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

kecuali jika filenya besar. Jika tidak, gunakan mis

find srcdir -type f/ |grep -v Default.png$ |xargs -ILIST cp LIST destdir/
no
sumber
1
Perintah pertama bukanlah yang diminta OP. Jika Default.pngada di dua direktori, itu akan menggantikan satu di destdirdengan yang di srcdir, lalu menghapus yang disalin Default.png. Sebaliknya, OP ingin mempertahankan Default.pngyang sudah ada destdir.
SnowFrog
2
bagaimana kalau default.png sudah ada di destdir? Solutioun Anda tidak akan berhasil.
Iman Mohamadi
2

Ini berfungsi dengan baik untuk menyalin semuanya kecuali modul node :) selamat menikmati dan terima kasih atas jawaban di atas yang baru saja saya tambahkan. Rsync lebih baik menurut saya daripada CP karena Anda dapat melihat bilah kemajuan tanpa memintanya.

   rsync -av fromDirectory/ ToDirectory/ --exclude=node_modules
Josh
sumber
0
cp `ls | grep -v Default.png` destdir
Will Hartung
sumber
5
Ini lebih mungkin menghasilkan kesalahan daripada melakukan apa yang Anda inginkan.
Dijeda sampai pemberitahuan lebih lanjut.
-1
# chattr +i /files_to_exclude
# cp source destination
# chattr -i /files_to_exclude
Ivan Grynenko
sumber
-2

gunakan parameter ekspansi shell dengan regex

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

Semuanya akan disalin kecuali not_to_copy_file

- jika ada yang salah dengan ini. harap Tentukan!

alex
sumber
1
Selamat datang di SO. Sayangnya jawaban Anda tidak benar. Ekspresi tanda kurung ( [...]) berisi sekumpulan karakter untuk dicocokkan, sedangkan awalan ^akan menyebabkan kecocokan pelengkap dari karakter yang terdaftar. Pada contoh berikut, file yang tidak akan terdaftar: touch not_to_copy_file to_copy_file ; ls [^not_to_copy_file]*karena semua nama file yang dimulai dengan salah satu karakter berikut akan dikecualikan: _cefilnopty.
rtx13