Jak skopiować niektóre, ale nie wszystkie pliki?


54

Tak więc możesz używać *symbolu wieloznacznego dla wszystkich plików, gdy używasz go cpw kontekście katalogu. Czy istnieje sposób na skopiowanie wszystkich plików oprócz xpliku?

Odpowiedzi:


42

W bashmożesz użyć extglob:

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

gdzie !(b*)wyklucz wszystkie b*pliki.

Możesz później wyłączyć za extglobpomocą

 $ shopt -u extglob

Czy wiesz, czy istnieje coś równoważnego dla powłoki tcsh?
Levon

Niestety nie. Wydaje się, że findto jedyny sposób na tcsh:find . -maxdepth 1 ! -name "exclude*" -exec cp -t destination {} \+
pośpiech

50

Rsync radzi sobie z tym ładnie.

Przykład skopiuj wszystko: rsync -aP /folder1/* /folder/2

Przykład skopiuj wszystko z wyłączeniem: rsync -aP --exclude=x /folder1/* /folder2/

-aPPrzełącznik:

a: Podobne do cp -arekurencyjnego itp. P: Pokazuje postęp, miłą cechę rsync.


5
I zobacz tę odpowiedź w celu uzyskania krótkiego przewodnika po popularnych listach wykluczeń rsync.
Gilles 'SO - przestań być zły'

1
W systemie darwin / MacOS używaj -rPzamiast, -aPjeśli chcesz się powtarzać. -asłuży do archiwizacji. Nie jestem pewien, czy to się zmieniło, czy po prostu inaczej na MacOS.
jpoveda

rsyncma opcję uczynienia go rekurencyjnym. Przykład: rsync --recursive -P --exclude=x /folder1/* /folder2/. (Testowane tylko na Ubuntu)
n1k31t4

12

To nie jest funkcja cp, jest to funkcja twojej powłoki (rozwija się tak, *że oznacza wszystkie pliki bez kropek), więc odpowiedź zależy od używanej powłoki . Na przykład zshobsługuje tę składnię:

$ cp ^x /path/to/destination

Gdzie ^xoznacza „wszystkie pliki oprócz x

Możesz także łączyć wzorce wyboru i usuwania zaznaczenia, np. Aby skopiować wszystkie pliki wav oprócz tych zawierających xyz, możesz użyć:

cp *.wav~*xyz*

Jakieś komentarze na temat bash?
Chad Harrison

@hydroparadise Nie wiem dużo o bashu, ale ta odpowiedź wydaje się to obejmować
Michael Mrozek

Co z tcsh? Ktoś wie?
Levon

4

Można to również zrobić w zwykłej starej (przenośnej / kompatybilnej) powłoce Bourne'a na wiele sposobów za pomocą standardowych narzędzi w znacznie mniej elegancki sposób niż przy użyciu zaawansowanego globowania powłoki lub poleceń z wbudowanymi opcjami wykluczania.

Jeśli nie ma zbyt wielu plików (i nie zawiera nazw, w tym spacji i / lub podziałów wierszy), może to być sposób:

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

Oczywiście bashnarzędzia GNU są świetne i wydajne, ale wciąż nie zawsze są dostępne. Jeśli zamierzasz umieścić go w przenośnym skrypcie, poleciłbym findjak w komentarzu Rush.


2
Uważam, że ostatnia część twojej odpowiedzi po prostu odwraca uwagę od tematu. Poza tym „Unix” nie jest już złotym standardem (jeśli w ogóle był). To po prostu nie jest istotne, jeśli coś jest „Unixowe” lub już nie, pomimo tego, że tytuł tej strony to „Unix i Linux”.
Alexander

2
DOBRZE. Zamiast tego przeniosłem tutaj komentarz: Unix to nie GNU. Zgadzam się, że „unikalność” rzeczy nie jest zbyt interesująca, ale nadal wierzę w przenośność i trochę wiem o twojej historii.
MattBianco

W pełni się z tobą zgódź.
Alexander

2

Jeśli chcesz skopiować wszystko z folderu (łącznie z podfolderami) do określonego podkatalogu:

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

Działa z sh, bash, zsh (przynajmniej).


1
Przekonaj mnie, że to nie to samo, cocp -R * subdir/
roaima,

1
Jeśli użyjesz tego polecenia „cp -R * subdir /”, bash / zsh spróbuje skopiować „subdir” rekurencyjnie. Kończy się błąd: „nazwa jest za długa (nie skopiowana)”.
user2707671

Słuszna uwaga. Twoja sugestia próbuje uniknąć ostrzeżenia z cp(nie z bash/ sh), „ cp: cannot copy a directory, ‘subdir’, into itself, ‘subdir/subdir’”. Kopiowanie jest jednak prawidłowe. Niestety twój wariant zrywa z każdą nazwą pliku zawierającą spację lub interpunkcję wrażliwą na powłokę. Zobacz unix.stackexchange.com/q/128985/135943
roaima

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.