Jak użyć polecenia „cp”, aby wykluczyć określony katalog?
410
Chcę skopiować wszystkie pliki w katalogu oprócz niektórych plików w określonym podkatalogu. Zauważyłem, że polecenie „cp” nie ma opcji --exclude. Jak mogę to osiągnąć?
Zauważ, że opcja katalog thefoldertoexcludepo --excludejest względna w stosunku do sourcefolder, tj sourcefolder/thefoldertoexclude.
Możesz również dodać -ndo trybu próbnego, aby zobaczyć, co zostanie skopiowane przed wykonaniem prawdziwej operacji, a jeśli wszystko jest w porządku, usuń -nz wiersza polecenia.
Zgadzam się, że nie można pobić prostoty i siły--exclude
Matthew Wilcoxson
31
jest thefoldertoexcludewzględny sourcefolderlub aktualny działający reż? dzięki
Beebee,
46
Jest względny do folderu źródłowego. Spowoduje to wykluczenie kopiowania folderu source / .git. rsync -r --exclude '.git' źródło target
orkoden
15
Może się mylę, ale myślę, że dobrą praktyką jest dodawanie „przełączników” przed „parametrami”. Również strona man raportów rsync - wyklucz użyteczne jak ze składnią "=" lub bez. Tak więc, aby ustandaryzować się w różnych systemach operacyjnych, rsync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolderużyłbym - w każdym razie upvote dla rsync zamiast find, ponieważ możesz łatwo użyć bezwzględnych ścieżek do źródła, podczas gdy w find jest trudniejsze, ponieważ używa {}dst.
Xavi Montero,
1
@mamun Oczywiście np. ze zdalnego serwera na komputer lokalny: $ rsync [email protected]:/var/www/mypage /var/www/mylocalpage/lub z lokalnego na zdalny$ rsync /var/www/mylocalpage/ [email protected]:/var/www/mypage
sobi3ch
84
Cóż, gdyby wykluczenie pewnych wzorców nazw plików musiało być wykonane przez każde narzędzie uniksowe (np. Cp, mv, rm, tar, rsync, scp, ...), nastąpiłoby ogromne powielanie wysiłku. Zamiast tego, takie rzeczy można zrobić w ramach globowania , tj. Za pomocą powłoki.
Więc po prostu umieść wzór w środku !(), a to neguje dopasowanie. Wzorzec może być dowolnie złożony, zaczynając od wyliczenia poszczególnych ścieżek (jak pokazuje Vanwaril w innej odpowiedzi): od wyrażeń !(filename1|path2|etc3)regularnych z gwiazdami i klasami postaci. Szczegółowe informacje można znaleźć na stronie podręcznika.
Myślę, że potrzebujesz -pathargumentu do przetestowania hierarchii ścieżek, a nie -iname
James Murty
3
Na końcu będziesz też potrzebować średnika:find . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
Matthew Wilcoxson
1
Wow, nie pozwoli mi to: „Edycja musi mieć co najmniej 6 znaków”!
Matthew Wilcoxson
1
@MatthewWilcoxson Meh. Ograniczenia te zostaną zniesione, gdy tylko zdobędziesz trochę więcej przedstawicieli. Odpowiednio zredagowałem odpowiedź. Dzięki jeszcze raz!
Linus Kleen
1
@Henning dlaczego nie rsync? Bo może nie być obecny w systemie! natomiast find, cpjest zawsze na swoich miejscach. A może ty od facetów, którzy zainstalowali 2 gigabajty rzeczy, aby robić proste rzeczy?
rsyncjest w rzeczywistości dość trudne. muszę wykonać wiele testów, aby to zadziałało.
Powiedzmy, że chcesz skopiować /var/www/htmldo /var/www/devale muszą wykluczyć/var/www/html/site/video/ katalog może ze względu na swoją wielkość. Poleceniem byłoby:
/Potrzebny jest ostatni ukośnik w źródle, w przeciwnym razie skopiuje on również katalog źródłowy, a nie jego zawartość i stanie się /var/www/dev/html/xxxx, co może nie jest tym, czego chcesz.
The --excludeścieżka jest względna do źródła bezpośrednio. Nawet jeśli podasz pełną ścieżkę absolutną, to nie zadziała.
-vjest dla pełnego, -asłuży do trybu archiwizacji, co oznacza, że chcesz rekurencji i chcesz zachować prawie wszystko.
To modyfikacja odpowiedzi Linusa Kleena. Jego odpowiedź nie działała dla mnie, ponieważ będzie. dodane przed ścieżką do pliku, której nie lubi cp (ścieżka wyglądałaby jak source / .destination / file).
Może nie całkiem - ale to jedyna znaleziona tutaj opcja, która działa ze cpstandardową powłoką POSIX sh.
tomekwi
1
Ta odpowiedź jest dramatycznie niedoceniana. Jest to najbardziej kompatybilna, najłatwiejsza do odczytania i łatwa do zrozumienia odpowiedź. Brawa, nie wiem, dlaczego o tym nie pomyślałem.
Robert Talada
Dzięki @RobertTalada, jak daleko odejdzie odpowiedź? ️🌈
Używam pętli „do while”, aby odczytać dane wyjściowe polecenia find. W tym przykładzie dopasowuję (zamiast wykluczam) pewne wzorce, ponieważ istnieje bardziej ograniczona liczba dopasowań wzorców, których chcę, niż których nie chcę. Możesz odwrócić logikę z -not przed flagami -iname:
Korzystam z powyższego, aby skopiować wszystkie pliki typu muzyki, które są nowsze na moim serwerze niż pliki w Western Digital TV Live Hub, które zamontowałem w / media / wd. Używam powyższego, ponieważ mam wiele plików DVD, MPEG, itp., Które chcę wykluczyć ORAZ z jakiegoś powodu rsync wygląda na to, że kopiuje, ale po spojrzeniu na urządzenie wd, pliki nie są tam pomimo braku błędy podczas rsync z tym poleceniem:
Pierwsza część to lswszystkie pliki, ale ukryte określone pliki z flagą -I. Wyjście lsjest używane jako standardowe wejście dla drugiej części. xargsbuduj i wykonuj polecenia cp -rf -t destdirze standardowego wejścia. flaga -roznacza kopiowanie katalogów rekurencyjnie, -foznacza kopiowanie plików siłą, które zastąpią pliki w destdir, -tokreśl docelową kopię katalogu do.
tar -c | tar -x
?Odpowiedzi:
rsync jest szybki i łatwy:
Możesz użyć
--exclude
wiele razy.Zauważ, że opcja katalog
thefoldertoexclude
po--exclude
jest względna w stosunku dosourcefolder
, tjsourcefolder/thefoldertoexclude
.Możesz również dodać
-n
do trybu próbnego, aby zobaczyć, co zostanie skopiowane przed wykonaniem prawdziwej operacji, a jeśli wszystko jest w porządku, usuń-n
z wiersza polecenia.źródło
--exclude
thefoldertoexclude
względnysourcefolder
lub aktualny działający reż? dziękirsync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolder
użyłbym - w każdym razie upvote dla rsync zamiast find, ponieważ możesz łatwo użyć bezwzględnych ścieżek do źródła, podczas gdy w find jest trudniejsze, ponieważ używa{}
dst.$ rsync [email protected]:/var/www/mypage /var/www/mylocalpage/
lub z lokalnego na zdalny$ rsync /var/www/mylocalpage/ [email protected]:/var/www/mypage
Cóż, gdyby wykluczenie pewnych wzorców nazw plików musiało być wykonane przez każde narzędzie uniksowe (np. Cp, mv, rm, tar, rsync, scp, ...), nastąpiłoby ogromne powielanie wysiłku. Zamiast tego, takie rzeczy można zrobić w ramach globowania , tj. Za pomocą powłoki.
grzmotnąć
man 1 bash
, / extglob .Przykład:
Więc po prostu umieść wzór w środku
!()
, a to neguje dopasowanie. Wzorzec może być dowolnie złożony, zaczynając od wyliczenia poszczególnych ścieżek (jak pokazuje Vanwaril w innej odpowiedzi): od wyrażeń!(filename1|path2|etc3)
regularnych z gwiazdami i klasami postaci. Szczegółowe informacje można znaleźć na stronie podręcznika.zsh
man 1 zshexpn
, / generowanie nazw plików .Możesz robić
setopt KSH_GLOB
i używać wzorców przypominających bash. Lub,Tak
x~y
dopasowuje wzorzecx
, ale wyklucza wzóry
. Ponownie, aby uzyskać szczegółowe informacje, patrz strona podręcznika.ryby nowe!
Ryba skorupa ma dużo ładniejszą odpowiedź do tego:
Dodatkowa wskazówka
Wpisz
cp *
, naciśnij CtrlX*i zobacz, co się stanie. to nie jest szkodliwe , obiecujęźródło
zsh
.setopt -u extglob
.rsync
Po co korzystać, kiedy możesz:Zakłada się, że struktura katalogu docelowego jest taka sama jak źródła.
źródło
-path
argumentu do przetestowania hierarchii ścieżek, a nie -inamefind . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
rsync
? Bo może nie być obecny w systemie! natomiastfind
,cp
jest zawsze na swoich miejscach. A może ty od facetów, którzy zainstalowali 2 gigabajty rzeczy, aby robić proste rzeczy?źródło
# $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 }
Najłatwiejszy sposób, w jaki znalazłem, gdzie można skopiować wszystkie pliki oprócz plików i folderów, po prostu dodając ich nazwy w nawiasach:
źródło
-bash: !: event not found
Rozszerzając komentarz mvds , to działa dla mnie
źródło
Jest względny do katalogu źródłowego.
Spowoduje to wykluczenie
source/.git
kopiowania katalogu .źródło
rsync
i najpierw spróbuj z opcją -n, aby zobaczyć, co zostanie skopiowane
źródło
Zakładam, że używasz bash lub dash. Czy to zadziała?
Wykonanie polecenia ls z wyłączeniem plików, których nie chcesz, i użycie go jako pierwszego argumentu dla cp
źródło
ls
i po prostu zrobićcp !(file1|file1) dest
.cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
Inną prostszą opcją jest instalacja i użycie rsync, który ma opcję --exclude-dir i może być używany zarówno do plików lokalnych, jak i zdalnych.
źródło
rsync
jest w rzeczywistości dość trudne. muszę wykonać wiele testów, aby to zadziałało.Powiedzmy, że chcesz skopiować
/var/www/html
do/var/www/dev
ale muszą wykluczyć/var/www/html/site/video/
katalog może ze względu na swoją wielkość. Poleceniem byłoby:rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev
Niektóre zastrzeżenia :
/
Potrzebny jest ostatni ukośnik w źródle, w przeciwnym razie skopiuje on również katalog źródłowy, a nie jego zawartość i stanie się/var/www/dev/html/xxxx
, co może nie jest tym, czego chcesz.The
--exclude
ścieżka jest względna do źródła bezpośrednio. Nawet jeśli podasz pełną ścieżkę absolutną, to nie zadziała.-v
jest dla pełnego,-a
służy do trybu archiwizacji, co oznacza, że chcesz rekurencji i chcesz zachować prawie wszystko.źródło
Edycja: zapomniałem również wykluczyć ścieżkę docelową (w przeciwnym razie rekurencyjnie skopiuje).
źródło
To modyfikacja odpowiedzi Linusa Kleena. Jego odpowiedź nie działała dla mnie, ponieważ będzie. dodane przed ścieżką do pliku, której nie lubi cp (ścieżka wyglądałaby jak source / .destination / file).
To polecenie działało dla mnie:
find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;
polecenie --parents zachowuje strukturę katalogów.
źródło
Po prostu przenieś go tymczasowo do ukrytego katalogu (i zmień jego nazwę później, jeśli chcesz).
źródło
cp
standardową powłoką POSIXsh
.źródło
Używam pętli „do while”, aby odczytać dane wyjściowe polecenia find. W tym przykładzie dopasowuję (zamiast wykluczam) pewne wzorce, ponieważ istnieje bardziej ograniczona liczba dopasowań wzorców, których chcę, niż których nie chcę. Możesz odwrócić logikę z -not przed flagami -iname:
Korzystam z powyższego, aby skopiować wszystkie pliki typu muzyki, które są nowsze na moim serwerze niż pliki w Western Digital TV Live Hub, które zamontowałem w / media / wd. Używam powyższego, ponieważ mam wiele plików DVD, MPEG, itp., Które chcę wykluczyć ORAZ z jakiegoś powodu rsync wygląda na to, że kopiuje, ale po spojrzeniu na urządzenie wd, pliki nie są tam pomimo braku błędy podczas rsync z tym poleceniem:
źródło
Pierwsza część to
ls
wszystkie pliki, ale ukryte określone pliki z flagą-I
. Wyjściels
jest używane jako standardowe wejście dla drugiej części.xargs
buduj i wykonuj poleceniacp -rf -t destdir
ze standardowego wejścia. flaga-r
oznacza kopiowanie katalogów rekurencyjnie,-f
oznacza kopiowanie plików siłą, które zastąpią pliki wdestdir
,-t
określ docelową kopię katalogu do.źródło
cp -r
ls -A | grep -v "Excluded_File_or_folder"
../$target_location -vźródło