BASH copia todos os arquivos, exceto um

110

Eu gostaria de copiar todos os arquivos de um diretório, exceto um chamado Default.png. Parece que existem várias maneiras de fazer isso. O que parece mais eficaz para você?

Joe Cannatti
fonte
Por que você precisa que ele ignore esse arquivo, em vez de apenas excluí-lo depois de copiá-lo? Já existe no diretório de destino?
Lasse V. Karlsen
1
Sim, um arquivo com o mesmo nome já está morando no diretório de destino.
Joe Cannatti
@ LasseV.Karlsen: Ou você pode querer economizar tempo ao copiá-lo, se for um arquivo grande. Estou interessado nisso, mas excluindo um diretório em vez de um arquivo.
Nikana Reklawyks de

Respostas:

54

Simples, se src/contiver apenas arquivos:

find src/ ! -name Default.png -exec cp -t dest/ {} +

Se src/tiver subdiretórios, isso os omite, mas copia os arquivos dentro deles:

find src/ -type f ! -name Default.png -exec cp -t dest/ {} +

Se src/tiver subdiretórios, isso não ocorrerá novamente:

find src/ -type f -maxdepth 1 ! -name Default.png -exec cp -t dest/ {} +
John Kugelman
fonte
5
Isso acabou sendo o melhor para mim porque parece que o OS X vem sem glob habilitado.
Joe Cannatti
6
@Max \;executa o comando uma vez por arquivo. +executa o comando uma vez e passa todos os nomes de arquivo para ele de uma vez (sujeito ao limite de comprimento da linha de comando). +é um pouco mais eficiente em geral.
John Kugelman
149

Deve ser o seguinte:

cp -r !(Default.png) /dest

Se estiver copiando para uma pasta aninhada na pasta atual (chamada de exemplo no caso abaixo), você também precisa omitir esse diretório:

cp -r !(Default.png|example) /example
Jon
fonte
17
Isso produz -bash:!: Evento não encontrado
Joe Cannatti
Você está copiando os arquivos para uma pasta aninhada na pasta da qual está copiando?
Jon
47
Isso precisa shopt -s extglobfuncionar, se tiver sido desativado.
Barry Kelly
5
Parece que o OS X precisa ser usado shopt -s extglobconforme descrito por @BarryKelly. Com isso, funciona perfeitamente.
Kat
Anos no Bash e não sabia sobre !()... Linda! Para aqueles que --como eu-- sentem que é hora de estudar / revisar o bash , aqui estão os links relevantes relacionados a esta pergunta / resposta: shopt / extglob e o padrão .
Brandt
73

O rsync tem sido meu substituto cp / scp por muito tempo:

rsync -av from/ to/ --exclude=Default.png

-a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose               increase verbosity
matja
fonte
Se eu quiser excluir dois arquivos diferentes, como faço isso?
Pulkit Bansal
múltiplos argumentos --exclude = são suportados. E não se esqueça do -rargumento se estiver sincronizando diretórios
Rian Sanderson
5

Eu apenas faria:

cp srcdir/* destdir/ ; rm destdir/Default.png

a menos que os arquivos sejam grandes. Caso contrário, use por exemplo

find srcdir -type f/ |grep -v Default.png$ |xargs -ILIST cp LIST destdir/
nos
fonte
1
O primeiro comando não é o que o OP pediu. Se Default.pngexistir nos dois diretórios, ele substituirá o de dentro destdirpelo de e srcdir, em seguida, excluirá o copiado Default.png. Em vez disso, o OP deseja manter o Default.pngque já existe em destdir.
SnowFrog
2
que tal default.png já existe em destdir? Sua solução não funcionará.
Iman Mohamadi
2

Isso funciona muito bem para copiar tudo, exceto módulos de nó :) divirta-se e, graças às respostas acima, acabei de adicionar a ele. Rsync é melhor na minha opinião do que CP, pois você pode ver a barra de progresso sem pedir por isso.

   rsync -av fromDirectory/ ToDirectory/ --exclude=node_modules
Josh
fonte
0
cp `ls | grep -v Default.png` destdir
Will Hartung
fonte
5
É mais provável que isso produza erros do que o que você pretende.
Pausado até novo aviso.
-1
# chattr +i /files_to_exclude
# cp source destination
# chattr -i /files_to_exclude
Ivan Grynenko
fonte
-2

use o parâmetro de expansão do shell com regex

cp /<path>/[^not_to_copy_file]* .

Tudo será copiado, exceto o not_to_copy_file

- se algo está errado com isso. por favor especifique !

alex
fonte
1
Bem-vindo ao SO. Infelizmente, sua resposta não está correta. O colchete expresssion ( [...]) contém um conjunto de caracteres para coincidir, enquanto um líder ^causará uma correspondência do complemento dos caracteres listados. No exemplo a seguir, nem arquivo será listada: touch not_to_copy_file to_copy_file ; ls [^not_to_copy_file]*porque todos os nomes que começam com qualquer um dos seguintes caracteres serão excluídos: _cefilnopty.
rtx13