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ąć?
tar -c | tar -x?
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ąć?
tar -c | tar -x?
Odpowiedzi:
rsync jest szybki i łatwy:
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude
Możesz użyć --excludewiele razy.
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude
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.
--exclude
thefoldertoexcludewzględny sourcefolderlub aktualny działający reż? dzięki
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.
$ rsync user@example.com:/var/www/mypage /var/www/mylocalpage/lub z lokalnego na zdalny$ rsync /var/www/mylocalpage/ user@example.com:/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.
man 1 bash, / extglob .
Przykład:
$ shopt -s extglob $ echo images / * images / 004.bmp images / 033.jpg images / 1276338351183.jpg images / 2252.png $ echo images /! (*. jpg) images / 004.bmp images / 2252.png
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.
man 1 zshexpn, / generowanie nazw plików .
Możesz robić setopt KSH_GLOBi używać wzorców przypominających bash. Lub,
% setopt EXTENDED_GLOB % obrazów echa / * images / 004.bmp images / 033.jpg images / 1276338351183.jpg images / 2252.png % echo images / * ~ * .jpg images / 004.bmp images / 2252.png
Tak x~ydopasowuje wzorzec x, ale wyklucza wzór y. Ponownie, aby uzyskać szczegółowe informacje, patrz strona podręcznika.
Ryba skorupa ma dużo ładniejszą odpowiedź do tego:
🐟 cp (ciąg pasujący -v '* .excluded.names' - srcdir / *) destdir
Wpisz cp *, naciśnij CtrlX*i zobacz, co się stanie. to nie jest szkodliwe , obiecuję
zsh.
setopt -u extglob.
rsyncPo co korzystać, kiedy możesz:
find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'
Zakłada się, że struktura katalogu docelowego jest taka sama jak źródła.
-pathargumentu do przetestowania hierarchii ścieżek, a nie -iname
find . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
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?
cp -r `ls -A | grep -v "c"` $HOME/
# $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:
shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
-bash: !: event not found
Rozszerzając komentarz mvds , to działa dla mnie
cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
Jest względny do katalogu źródłowego.
Spowoduje to wykluczenie source/.gitkopiowania katalogu .
rsync -r --exclude '.git' source target
rsync
rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/
i najpierw spróbuj z opcją -n, aby zobaczyć, co zostanie skopiowane
Zakładam, że używasz bash lub dash. Czy to zadziała?
shopt -s extglob # sets extended pattern matching options in the bash shell
cp $(ls -laR !(subdir/file1|file2|subdir2/file3)) destination
Wykonanie polecenia ls z wyłączeniem plików, których nie chcesz, i użycie go jako pierwszego argumentu dla cp
lsi po prostu zrobić cp !(file1|file1) dest.
cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
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:
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.
-vjest dla pełnego, -asłuży do trybu archiwizacji, co oznacza, że chcesz rekurencji i chcesz zachować prawie wszystko.
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir
Edycja: zapomniałem również wykluczyć ścieżkę docelową (w przeciwnym razie rekurencyjnie skopiuje).
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.
Po prostu przenieś go tymczasowo do ukrytego katalogu (i zmień jego nazwę później, jeśli chcesz).
mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname
cpstandardową powłoką POSIX sh.
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/
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:
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
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:
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/
ls -I "filename1" -I "filename2" | xargs cp -rf -t destdir
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.
cp -r ls -A | grep -v "Excluded_File_or_folder"../$target_location -v