Bagaimana cara menyalin beberapa, tetapi tidak semua file?


54

Jadi, Anda dapat menggunakan *sebagai kartu liar untuk semua file saat menggunakan cpdalam konteks direktori. Apakah ada cara untuk menyalin semua file kecuali xfile?

Jawaban:


42

Di dalam bashAnda dapat menggunakan extglob:

 $ shopt -s extglob  # to enable extglob
 $ cp !(b*) new_dir/

di mana !(b*)mengecualikan semua b*file.

Anda nanti dapat menonaktifkan extglobdengan

 $ shopt -u extglob

Apakah Anda tahu jika ada sesuatu yang setara dengan shell tcsh?
Levon

Sayangnya saya tidak. Sepertinya findadalah satu-satunya cara di tcsh:find . -maxdepth 1 ! -name "exclude*" -exec cp -t destination {} \+
buru

50

Rsync menangani ini dengan baik.

Contoh salin semua: rsync -aP /folder1/* /folder/2

Contoh salin semua dengan pengecualian: rsync -aP --exclude=x /folder1/* /folder2/

The -aPswitch:

a: Mirip dengan cp -a, rekursif, dll. P: Menampilkan kemajuan, fitur bagus dari rsync.


5
Dan lihat jawaban ini untuk panduan singkat ke daftar pengecualian rsync umum.
Gilles 'SANGAT berhenti menjadi jahat'

1
Di darwin / MacOS, gunakan -rPalih-alih -aPjika Anda ingin berulang. -aadalah untuk pengarsipan. Tidak yakin apakah ini berubah atau hanya berbeda pada MacOS.
jpoveda

rsyncmemang memiliki opsi untuk membuatnya rekursif. Contoh: rsync --recursive -P --exclude=x /folder1/* /folder2/. (Diuji hanya pada Ubuntu)
n1k31t4

12

Ini bukan fitur dari cp, itu fitur shell Anda (itu memperluas *berarti semua file non-dot), jadi jawabannya tergantung pada shell yang Anda gunakan. Misalnya, zshmendukung sintaks ini:

$ cp ^x /path/to/destination

Dimana ^xartinya "semua file kecuali x"

Anda juga dapat menggabungkan pola seleksi dan de-seleksi, misalnya untuk menyalin semua file wav kecuali yang mengandung xyz, Anda dapat menggunakan:

cp *.wav~*xyz*

Ada komentar bash?
Chad Harrison

@ hidroparadise Saya tidak tahu banyak tentang bash, tetapi jawaban ini sepertinya menutupinya
Michael Mrozek

Bagaimana dengan tcsh? Adakah yang tahu
Levon

4

Dapat juga dilakukan dalam shell bourne biasa (portabel / kompatibel) dalam berbagai cara dengan alat standar dalam cara yang jauh lebih elegan daripada menggunakan globbing shell canggih atau perintah dengan opsi built-in-exclusion.

Jika tidak ada terlalu banyak file (dan tidak dengan nama termasuk spasi dan / atau linebreak), ini bisa menjadi caranya:

cp `ls | egrep -v '^excludename$'` destdir/.

Tentu, bashdan alat-alat GNU hebat dan kuat, tetapi mereka tidak selalu tersedia. Jika Anda bermaksud memasukkannya ke dalam skrip portabel, saya akan merekomendasikan findseperti dalam komentar oleh Rush.


2
Saya menemukan bahwa bagian terakhir dari jawaban Anda hanya mengalihkan perhatian dari topik yang sedang dibahas. Selain itu, "Unix" bukan standar emas lagi (jika pernah ada). Hanya saja tidak relevan jika ada sesuatu yang "Unix" atau tidak lagi, meskipun judul situs ini adalah "Unix dan Linux".
Alexander

2
BAIK. Saya memindahkan komentar ke sini: Unix bukan GNU. Saya setuju bahwa "keanehan" sesuatu tidak terlalu menarik, tetapi saya masih percaya pada portabilitas dan mengetahui sedikit tentang sejarah Anda.
MattBianco

Sepenuhnya setuju dengan Anda di sana.
Alexander

2

Jika Anda ingin menyalin semua yang ada di folder (termasuk subfolder) ke sub-direktori tertentu:

cp -R $(ls | grep -v '^subdir$') subdir/

Bekerja dengan sh, bash, zsh (setidaknya).


1
Meyakinkan saya ini bukan niat yang sama dengancp -R * subdir/
roaima

1
Jika Anda menggunakan perintah "cp -R * subdir /", bash / zsh mencoba menyalin 'subdir' secara rekursif. Anda berakhir dengan kesalahan: "nama terlalu panjang (tidak disalin)".
user2707671

Poin bagus. Saran Anda berusaha menghindari peringatan dari cp(bukan dari bash/ sh), " cp: cannot copy a directory, ‘subdir’, into itself, ‘subdir/subdir’". Salinan tidak lengkap dengan benar. Sayangnya varian Anda rusak dengan nama file yang mengandung tanda baca spasi atau shell-sensitive. Lihat unix.stackexchange.com/q/128985/135943
roaima

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.