Quero copiar todos os arquivos em um diretório, exceto alguns arquivos em um subdiretório específico. Notei que o comando 'cp' não tinha uma opção --exclude. Então, como posso conseguir isso?
tar -c | tar -x
?
Quero copiar todos os arquivos em um diretório, exceto alguns arquivos em um subdiretório específico. Notei que o comando 'cp' não tinha uma opção --exclude. Então, como posso conseguir isso?
tar -c | tar -x
?
Respostas:
O rsync é rápido e fácil:
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude
Você pode usar --exclude
múltiplos tempos.
rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude
Observe que a opção dir thefoldertoexclude
after --exclude
é relativa a sourcefolder
, ie sourcefolder/thefoldertoexclude
,.
Além disso, você pode adicionar -n
para execução a seco para ver o que será copiado antes de executar a operação real e, se estiver tudo bem, remova-o -n
da linha de comando.
--exclude
thefoldertoexclude
parente sourcefolder
ou o diretório de trabalho atual? graças
rsync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolder
- de qualquer maneira, voto positivo para o rsync, em vez da localização, pois você pode facilmente usar caminhos absolutos para a fonte, enquanto a localização é mais complicada, pois usa {}
o dst.
$ rsync user@example.com:/var/www/mypage /var/www/mylocalpage/
ou de local para remoto$ rsync /var/www/mylocalpage/ user@example.com:/var/www/mypage
Bem, se a exclusão de certos padrões de nome de arquivo tivesse que ser executada por todo utilitário de arquivo unix-ish (como cp, mv, rm, tar, rsync, scp, ...), uma imensa duplicação de esforço ocorreria. Em vez disso, essas coisas podem ser feitas como parte do globbing , ou seja, pela sua concha.
man 1 bash
, / extglob .
Exemplo:
$ shopt -s extglob $ imagens de eco / * images / 004.bmp images / 033.jpg images / 1276338351183.jpg images / 2252.png $ imagens de eco /! (*. jpg) images / 004.bmp images / 2252.png
Então você coloca um padrão dentro !()
, e isso anula a correspondência. O padrão pode ser arbitrariamente complexo, a partir da enumeração de caminhos individuais (como Vanwaril mostra em outra resposta): !(filename1|path2|etc3)
para coisas semelhantes a expressões regulares com estrelas e classes de caracteres. Consulte a página de manual para obter detalhes.
man 1 zshexpn
, / geração de nome de arquivo .
Você pode fazer setopt KSH_GLOB
e usar padrões semelhantes ao bash. Ou,
% setopt EXTENDED_GLOB % de imagens de eco / * images / 004.bmp images / 033.jpg images / 1276338351183.jpg images / 2252.png % imagens de eco / * ~ * .jpg images / 004.bmp images / 2252.png
Então x~y
corresponde ao padrão x
, mas exclui o padrão y
. Mais uma vez, para obter detalhes completos, consulte a página de manual.
A casca do peixe tem uma resposta muito mais bonita para isso:
🐟 cp (sequência de caracteres -v '* .excluded.names' - srcdir / *) destdir
Digite cp *
, clique CtrlX*e veja o que acontece. não é prejudicial eu prometo
zsh
embora.
setopt -u extglob
.
Por que usar rsync
quando você pode fazer:
find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'
Isso pressupõe que a estrutura de diretórios de destino seja igual à da origem.
-path
argumento para hierarquias de caminho de teste, não -iname
find . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
rsync
? Porque pode não estar presente no sistema! enquanto find
, cp
está sempre em seus lugares. Ou você é do tipo de pessoa que instalou 2 galhos de coisas para fazer coisas simples?
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 }
A maneira mais fácil que encontrei, onde você pode copiar todos os arquivos, excluindo arquivos e pastas, apenas adicionando seus nomes entre parênteses:
shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
-bash: !: event not found
Expandindo o comentário do mvds , isso funciona para mim
cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
É relativo ao diretório de origem.
Isso excluirá o diretório source/.git
de ser copiado.
rsync -r --exclude '.git' source target
rsync
rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/
e primeiro tente com a opção -n para ver o que será copiado
Presumo que você esteja usando bash ou dash. Isso funcionaria?
shopt -s extglob # sets extended pattern matching options in the bash shell
cp $(ls -laR !(subdir/file1|file2|subdir2/file3)) destination
Fazendo um ls excluindo os arquivos que você não deseja e usando isso como o primeiro argumento para cp
ls
e simplesmente fazer cp !(file1|file1) dest
.
cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
rsync
é realmente bastante complicado. precisa fazer vários testes para fazê-lo funcionar.
Vamos dizer que você deseja copiar /var/www/html
para /var/www/dev
mas necessidade de excluir /var/www/html/site/video/
diretório talvez devido ao seu tamanho. O comando seria:
rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev
Alguma ressalva :
/
na fonte é necessária; caso contrário, ela também copiará o diretório de origem, em vez de seu conteúdo e se tornará /var/www/dev/html/xxxx
, o que talvez não seja o que você deseja.O --exclude
caminho é relativo à fonte diretamente. Mesmo se você colocar o caminho absoluto completo, ele não funcionará.
-v
é detalhado, -a
é para o modo de arquivo, o que significa que você deseja recursão e deseja preservar quase tudo.
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir
Editar: esqueceu de excluir também o caminho de destino (caso contrário, ele copiaria recursivamente).
Esta é uma modificação da resposta de Linus Kleen. Sua resposta não funcionou para mim porque haveria um. adicionado na frente do caminho do arquivo que o cp não gosta (o caminho seria semelhante ao código-fonte / .destination / file).
Este comando funcionou para mim:
find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;
o comando --parents preserva a estrutura de diretórios.
Apenas mova-o temporariamente para um diretório oculto (e renomeie-o depois, se desejado).
mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname
cp
um shell POSIX padrão sh
.
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/
Eu uso um loop "do while" para ler a saída do comando find. Neste exemplo, estou correspondendo (em vez de excluir) determinados padrões, pois há um número mais limitado de correspondências de padrão que eu quero do que não quero. Você pode reverter a lógica com um -not na frente dos sinalizadores -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
Utilizo o acima para copiar todos os arquivos de tipo de música que são mais recentes no meu servidor que os arquivos em um Western Digital TV Live Hub que eu montei em / media / wd. Eu uso o acima exposto porque tenho muitos arquivos de DVD, mpegs etc. que desejo excluir E porque, por algum motivo, o rsync parece estar copiando, mas depois de olhar para o dispositivo wd, os arquivos não estão lá, apesar de não haver erros durante o rsync com este comando:
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
A primeira parte de ls
todos os arquivos, mas oculta arquivos específicos com sinalizador -I
. A saída de ls
é usada como entrada padrão para a segunda parte. xargs
construir e executar comando a cp -rf -t destdir
partir da entrada padrão. o sinalizador -r
significa copiar diretórios recursivamente, -f
significa copiar arquivos à força que sobrescreverá os arquivos no destdir
, -t
especifique o diretório de destino para o qual copiar.
cp -r ls -A | grep -v "Excluded_File_or_folder"
../$target_location -v