Belirli bir dizini hariç tutmak için 'cp' komutu nasıl kullanılır?


411

Belirli bir alt dizindeki bazı dosyalar dışında bir dizindeki tüm dosyaları kopyalamak istiyorum. 'Cp' komutunun bir --exclude seçeneği olmadığını fark ettim. Peki, bunu nasıl başarabilirim?



6
tar -c | tar -x?
mvds

1
@mvds, katılıyorum, '--exclude' ile katran kullanmak iyi bir fikir.
Huang F. Lei

Yanıtlar:


704

rsync hızlı ve kolaydır:

rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude

--excludeBirden çok kez kullanabilirsiniz .

rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude

Dir thefoldertoexcludeafter --excludeseçeneğinin sourcefolder, ör sourcefolder/thefoldertoexclude.

Ayrıca -n, gerçek işlemi gerçekleştirmeden önce nelerin kopyalanacağını görmek için kuru çalıştırma ekleyebilirsiniz ve her şey yolundaysa, -nkomut satırından kaldırın .


3
Kabul etti, basitliğini ve gücünü yenemezsin--exclude
Matthew Wilcoxson

31
şu anki çalışma dizinine göre veya thefoldertoexcludegöreceli sourcefoldermi? teşekkürler
Beebee

46
Kaynak klasöre göredir. Bu, kaynak / .git klasörünün kopyalanmasını engeller. rsync -r - '.git' kaynak hedefini
ekleyin

15
Belki yanılıyorum ama "parametreler" den önce "anahtarlar" eklemek iyi bir uygulama olduğunu düşünüyorum. Ayrıca rsync raporlarının man sayfası - "=" sözdiziminde ya da olmadan kullanılabilir. Bu yüzden işletim sistemlerinde standartlaştırmak rsync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolderiçin kullanacağım - zaten bulmak yerine rsync için upvote, çünkü kaynakta için mutlak yolları kolayca kullanabilirsiniz, çünkü dst'de olduğu gibi daha zor {}.
Xavi Montero

1
@mamun Elbette örneğin uzak sunucudan yerel makineye: $ rsync user@example.com:/var/www/mypage /var/www/mylocalpage/veya yerelden uzaktan kumandaya$ rsync /var/www/mylocalpage/ user@example.com:/var/www/mypage
sobi3ch

84

Eh, belirli dosya adı kalıplarının dışlanması her unix-ish dosya yardımcı programı tarafından gerçekleştirilmek zorunda olsaydı (cp, mv, rm, tar, rsync, scp, ... gibi), çabaların muazzam bir kopyası olur. Bunun yerine, bu tür şeyler globbing'in bir parçası olarak , yani kabuğunuz tarafından yapılabilir .

darbe

man 1 bash, / extglob .

Misal:

$ shopt -s extglob
$ echo images / *
resimler / 004.bmp resimler / 033.jpg resimler / 1276338351183.jpg resimler / 2252.png
$ echo images /! (*. jpg)
images / 004.bmp images / 2252.png

Yani içine sadece bir desen koyarsınız !()ve bu maçı reddeder. Patern, bireysel yolların numaralandırılmasından başlayarak (Vanwaril'in başka bir cevapta gösterdiği gibi): !(filename1|path2|etc3)yıldız ve karakter sınıflarıyla normal ifade benzeri şeylere keyfi olarak karmaşık olabilir . Ayrıntılar için kılavuz sayfasına bakınız.

zsh

man 1 zshexpn, / dosya adı oluşturma .

setopt KSH_GLOBBash benzeri desenler yapabilir ve kullanabilirsiniz. Veya,

% setopt EXTENDED_GLOB
% echo images / *
resimler / 004.bmp resimler / 033.jpg resimler / 1276338351183.jpg resimler / 2252.png
% echo images / * ~ * .jpg
images / 004.bmp images / 2252.png

Böylece x~ydesenle eşleşir x, ancak desen hariçtir y. Bir kez daha, tüm detaylar için manpage'e bakınız.


balık yeni!

Balık kabuk bir sahiptir daha güzel cevabı bu kadar:

🐟 cp (dize eşleşmesi -v '* .excluded.names' - srcdir / *) destdir

Bonus yanlışı

Yazın cp *, vurun CtrlX*ve sadece ne olduğunu görün. zararlı değil söz veriyorum


@MikhailGolubtsov belki de globbing özyinelemeli değildir ve her seferinde bir seviye çalışır. Düzenlendi. PS: olsa çalışır zsh.
ulidtko

3
Güzel bir bahşiş! Bu şekilde, tek öğeleri kolayca kaldırabilirsiniz. Çok teşekkürler!
18'de taffit

BTW, Bash'te genişletilmiş desen eşleme özelliklerini kapatmak için çalıştırın setopt -u extglob.
Rockallite

49

Neden rsyncyapabileceğinizi kullanmalısınız :

find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'

Bu, hedef dizin yapısının kaynağınkiyle aynı olduğunu varsayar.


8
Sanırım -pathyol hiyerarşilerini test etmek için argümana ihtiyacın var, -iname değil
James Murty

3
Ayrıca sonunda bir find . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
noktalı

1
Vay canına, bana izin vermiyor: "Düzenlemeler en az 6 karakter olmalı"!
Matthew Wilcoxson

1
@MatthewWilcoxson Meh. Biraz daha fazla destek kazanır kazanmaz bu kısıtlamalar kaldırılacaktır. Cevabı buna göre düzenledim. Tekrar teşekkürler!
Linus Kleen

1
@Henning neden olmasın rsync? Çünkü sistemde olmayabilir! iken find, cpher zaman yerlerinde. Ya da basit şeyler yapmak için 2gig malzeme yükleyen bir adam mısınız?
Reishin

37
cp -r `ls -A | grep -v "c"` $HOME/

1
Windows 10'da benim için çalıştı
.sh

Özel kaynak yolu kullanımını ve yalnızca bir dosya veya dizinin hariç tutulmasını kolaylaştıran bir kabuk işlevi yapılmıştır: # $1 = source path # $2 = destination path # $3 = filter copy_from_source_to_destination_except_filter() { cp -r $(ls -A $1 | grep -v -w $3 | awk -v path=$1 '{printf "%s/%s ", path, $1}') $2 }
ElectRocnic

boşluklu dizinlerle başarısız
Sérgio

27

Bulduğum en kolay yol, dosya ve klasörler hariç tüm dosyaları yalnızca parantez içine ekleyerek kopyalayabileceğiniz en kolay yol:

shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/

9
Benim için çalışmıyor. Ben olsun-bash: !: event not found
geneorama

8
shopt -s extglob (cp, rm ve diğerlerinde etkinleştirmek için bunu yürütün)
imkost



8

rsync

rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/

ve önce nelerin kopyalanacağını görmek için -n seçeneği ile deneyin


En iyi cevaba kıyasla fark / gelişme nedir?
etkinliğini azaltma

7

Sanırım bash ya da tire kullanıyorsun. Bu işe yarar mı?

shopt -s extglob  # sets extended pattern matching options in the bash shell
cp $(ls -laR !(subdir/file1|file2|subdir2/file3)) destination

İstemediğiniz dosyaları hariç bir ls yapmak ve bunu cp için ilk argüman olarak kullanmak


9
Ekstra atlayabilir lsve basitçe yapabilirsiniz cp !(file1|file1) dest.
Shawn Chin

-LaR kullanmayın. cp ile çakışan dize ekler. cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
LAL

5

Başka bir basit seçenek de --exclude-dir seçeneği olan ve hem yerel hem de uzak dosyalar için kullanılabilen rsync'i kurmak ve kullanmaktır.


4

rsyncaslında oldukça zor. çalışmasını sağlamak için birden fazla test yapmak zorunda.

Diyelim ki kopyalamak /var/www/htmlistediğiniz /var/www/devancak dizinin boyutu nedeniyle dizini hariç tutmanız gerekiyor /var/www/html/site/video/. Komut şöyle olur:

rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev

Bazı uyarılar :

  1. /Kaynaktaki son eğik çizgi gereklidir, aksi takdirde içeriği yerine kaynak dizini de kopyalar ve olur /var/www/dev/html/xxxx, ki bu belki istediğiniz şey değildir.
  2. --excludeYolu göreli kaynağa doğrudan. Tam mutlak yol koymuş olsanız bile, çalışmaz.

  3. -vayrıntılı için, özyineleme istediğiniz ve hemen hemen her şeyi korumak istediğiniz -aanlamına gelen arşiv modu içindir .


özel karakterlere ve beyaz alanlara önem veren basit bir çözüm
Sérgio

Mevcut üst yanıtın aksine parametreleri açıkladığınız için teşekkürler!
etkinliğini azaltma

3
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir

Düzenleme: Hedef yolu da hariç tutmayı unuttum (aksi takdirde yinelemeli olarak kopyalanır).


4
boşluk içeren dizin girişlerine dikkat edin.
Paulo Scardine

3

Bu Linus Klein'ın cevabının bir modifikasyonudur. Cevabı benim için işe yaramadı çünkü bir olurdu. cp'nin hoşlanmadığı dosya yolunun önüne eklendi (yol kaynak / .destination / file gibi görünecektir).

Bu komut benim için çalıştı:

find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;

--parents komutu dizin yapısını korur.


2

Geçici olarak gizli bir dizine taşıyın (ve istenirse daha sonra yeniden adlandırın).

mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname

1
Belki hoş değil - ama burada çalıştığım cpve standart bir POSIX kabuğu gibi bulduğum tek seçenek sh.
tomekwi

1
Bu cevabın önemi azdır. Bu en uyumlu, okunması en kolay ve anlaşılması kolay cevaptır. Kudos, neden düşünmediğimi bilmiyorum.
Robert Talada

Teşekkürler @RobertTalada, cevap bundan sonra ne kadar ileri gidecek? ️‍🌈
lama12345

1
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/

0

Ben find komutunun çıktısını okumak için bir "do while" döngü kullanın. Bu örnekte, istediğimden daha fazla sayıda desen eşleşmesi olduğundan belirli desenleri eşleştiriyorum (hariç tutmak yerine). -İname bayraklarının önünde -not ile mantığı tersine çevirebilirsiniz:

    find . -type f -iname "*.flac" -o -print0 -iname "*.mp3" -print0 -o -iname "*.wav" -print0 -o -iname "*.aac" -print0 -o -iname "*.wma" -print0 | while read -d $'\0' file; do cp -ruv "$file" "/media/wd/network_sync/music/$file"; done

Sunucumda, / media / wd dizinine taktığım Western Digital TV Live Hub'daki dosyalardan daha yeni olan tüm müzik türü dosyalarını kopyalamak için yukarıdakileri kullanıyorum. Yukarıdakileri kullanıyorum çünkü hariç tutmak istediğim bir sürü DVD dosyası, mpeg vb. bu komutla rsync sırasındaki hatalar:

    rsync -av --progress --exclude=*.VOB --exclude=*.avi --exclude=*.mkv --exclude=*.ts --exclude=*.mpg --exclude=*.iso --exclude=*ar --exclude=*.vob --exclude=*.BUP --exclude=*.cdi --exclude=*.ISO --exclude=*.shn --exclude=*.MPG --exclude=*.AVI --exclude=*.DAT --exclude=*.img --exclude=*.nrg --exclude=*.cdr --exclude=*.bin --exclude=*.MOV --exclude=*.goutputs* --exclude=*.flv --exclude=*.mov --exclude=*.m2ts --exclude=*.cdg --exclude=*.IFO --exclude=*.asf --exclude=*.ite /media/2TB\ Data/data/music/* /media/wd/network_sync/music/

0
ls -I "filename1" -I "filename2" | xargs cp -rf -t destdir 

İlk bölümde lsbayraklı gizli dosyalar hariç tüm dosyalar-I . Çıkışı lsikinci bölüm için standart girdi olarak kullanılır. Standart girişten xargskomut oluştur ve çalıştır cp -rf -t destdir. bayrak -raraçları dizinleri akıcı kopya -faraçlar içinde dosyaların üzerine hangi zorla dosyaları kopyalamak destdir, -thedef dizin kopyası belirtin.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.