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ć --exclude
wiele razy.
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude
Zauważ, że opcja katalog thefoldertoexclude
po --exclude
jest względna w stosunku do sourcefolder
, tj sourcefolder/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.
--exclude
thefoldertoexclude
względny sourcefolder
lub aktualny działający reż? dzięki
rsync -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 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_GLOB
i 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~y
dopasowuje 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
.
rsync
Po 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.
-path
argumentu 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
, cp
jest 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/.git
kopiowania 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
ls
i po prostu zrobić cp !(file1|file1) dest
.
cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
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.
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
cp
standardową 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 ls
wszystkie pliki, ale ukryte określone pliki z flagą -I
. Wyjście ls
jest używane jako standardowe wejście dla drugiej części. xargs
buduj i wykonuj polecenia cp -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 w destdir
, -t
określ docelową kopię katalogu do.
cp -r ls -A | grep -v "Excluded_File_or_folder"
../$target_location -v