Copie todos os arquivos e pastas, exceto os arquivos e pastas do subversion no OS X

14

Estou tentando copiar todos os arquivos e pastas de um diretório para outro, mas excluir determinados arquivos. Especificamente, quero excluir arquivos e pastas do subversion. No entanto, eu gostaria de uma solução geral, porém concisa.

Imagino que encontrarei a necessidade de excluir vários tipos de arquivos em um futuro próximo. Por exemplo, convém excluir .svn, * .bak e * .prj.

Aqui está o que eu montei, mas não está funcionando para mim. A primeira parte, encontrar obras, mas estou fazendo algo errado com xargs e cp . Eu tentei cp com e sem o -R. Além disso, estou usando o OS X e parece ter uma versão menos característica do xargs do que os sistemas Linux.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory
Michael Prescott
fonte
Posso estar errado, mas acho que isso é mais complicado do que você pensa. Mesmo que seu findcomando use corretamente -prunepara excluir itens .svn, você passa o -Rsinalizador para o cpqual diz que esse comando é recursivo. Quando isso acontece, você perde a granularidade que tinha no findcomando. Vou mexer nisso por um minuto, mas acho que a resposta é não usar -Rno cpcomando.
Telemachus
Parece funcionar para mim em um sistema Linux. Você pode ser mais específico sobre o que significa "não está funcionando"? Alguma mensagem de erro? Arquivos recebendo / não sendo copiados que você espera?
Pausado até novo aviso.
É a -Rbandeira, tenho certeza. Retire isso e você deve estar bem (embora você pode querer adicionar -mindepth 1a ignorar a pasta diretório principal que você não deseja copiar, presumo)
Telêmaco
Normalmente, faço essas coisas copiando tudo e excluindo os arquivos indesejados nos diretórios de destino. Isso geralmente é muito mais simples.
Jan Doggen

Respostas:

22

(Editado após a leitura da pergunta. O questionador diz que o rsync não está instalado)

Um possível problema com sua solução find / xargs são os espaços nos nomes dos arquivos. Para contornar isso, diga a find e xargs para usar um caractere nulo (ASCII 0) para separar os arquivos encontrados:

find ./sourcedirectory -not ( -name .svn -a -prune ) -print0 | xargs -0 -IFILES cp FILES ./destinationdirectory

Se você achar que o rsync está disponível, ainda acho que o rsync é a solução muito melhor:

Use rsync com a opção -C. Na página do manual rsync :

Este é um atalho útil para excluir uma ampla variedade de arquivos que você frequentemente não deseja transferir entre sistemas. Ele usa um algoritmo semelhante ao CVS para determinar se um arquivo deve ser ignorado.

Isso instruirá o rsync a ignorar esses padrões:

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state .nse_depinfo *~
#* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj 
*.so *.exe *.Z *.elc *.ln core .svn/ .git/ .bzr/

Por exemplo:

rsync -avC /path/to/source/directory /path/to/destination/directory

(observação: se você ainda não está familiarizado com o rsync, leia nessa página de manual sobre como o rsync lida com uma barra no caminho de origem. Ele se comporta de maneira diferente se você incluir a barra do que se não o fizer. Procure por 'barra final')

Doug Harris
fonte
Oh ratos, acabei de reler sua pergunta e vi que você disse que não tem o rsync instalado. No meu MacBook Pro (OS X 10.6.1), ele está em / usr / bin / rsync. Também foi instalado para mim no Tiger (10.4) e no Leopard (10.5).
Doug Harris
Tenho certeza de que você (e o OP) não deseja a -Rbandeira na xargsparte do comando.
Telemachus
Boa captura, copiei isso da pergunta original. Irá editar agora.
Doug Harris
1
Obrigado Doug! Uma coisa que eu prego: "use a ferramenta certa para o trabalho". Recentemente, vim do mundo Windows para o OSX e ainda estou me esquecendo da ignorância. Postei essa mesma pergunta em um canal linux e alguém disse rapidamente, basta usar "rsynch". Digitei "rsynch" no terminal e vi que não existia e continuei investigando a localização | abordagem xargs. Eu sou um pouco teimoso assim. De qualquer forma, o OSX tem "rsync" por padrão, e sua postagem foi muito útil. Ainda não tenho experiência suficiente aqui para saber o que é melhor, mas o rsync com certeza é muito mais conciso. Obrigado!
227 Michael Prescott
Se você fará algum trabalho com máquinas Linux além do seu trabalho no OS X, acho que vale a pena aprender como usar o rsync. Sua funcionalidade principal é a cópia inteligente das coisas alteradas (como a robocópia no Windows, se você estiver familiarizado com isso). Como ele copia apenas o delta, é uma ótima maneira de lidar com backups (que não são do Time Machine), implantações de código e similares.
Doug Harris
2

Não é uma solução geral, mas ... você pode usar o comando svn export para criar uma cópia da área de trabalho sem as pastas de metadados .svn.

Chris Nava
fonte
Para não ser ofensivo, mas não sei por que essa resposta está sendo votada. Estou ciente dos recursos do svn, mas "eu gostaria de uma solução geral, porém concisa. Imagino que encontrarei a necessidade de excluir vários tipos de arquivos em um futuro próximo"
Michael Prescott
2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

se você quiser, pode até colocar 'pv' ou algo semelhante entre os 2 processos tar.

akira
fonte
2

Uma maneira suja, mas rápida e concisa:

cp -r source destination
find destination -iname .svn |xargs rm -rf

Isso copia um diretório para outro (portanto, a opção recursiva -r) e, em seguida, apaga recursivamente qualquer coisa chamada .svn(ignorando maiúsculas e minúsculas).

michele
fonte
1

Eu faria isso de uma maneira diferente, usando o tar e seu mecanismo de exclusão.

De no diretório de destino:

tar -X excludefile -C source -f - . | tar xf -

Isso fará um cd para a origem, tará o conteúdo, excluindo o que está listado em excludefile e, em seguida, descompactá-lo para o diretório atual.

KeithB
fonte
Solução elegante, de fato.
Nick Stinemates 28/09/09
bem, é a mesma resposta que dei, logo depois. Além disso, você tem que estar no diretório de destino ... :)
akira
0

Resposta editada : O problema é que -Rtorna a cópia recursiva e você acaba copiando os arquivos ocultos. Aqui está o que eu usaria:

find source/  -mindepth 1 -not \( -name .svn -prune \) | xargs -Iitem cp item target/

O -mindepth 1sinalizador indica findpara ignorar o diretório de nível superior. Como você deseja copiar todo o conteúdo desse diretório para um novo diretório de nível superior, presumo que você não queira isso.

Como Chris Nava diz em sua resposta , já existe uma maneira interna de fazer isso se estamos falando sobre pastas SVN, mas como você pediu uma solução mais geral, isso pode ajudar um pouco.

Telêmaco
fonte
Obrigado Telêmaco, é útil. Não tenho experiência para criticar, mas repetirei o que me disseram desde o meu post original. "xargs is broken" O comentarista desconhecido do irc que me disse que me inspirou a olhar um pouco mais e acho que a resposta de Doug Harris aborda o problema. Isso diz ao xargs para usar caracteres nulos. Eu acho que é o interruptor -0?
Michael Prescott
@ Michael: xargsnão está quebrado, mas em sistemas Unix, o padrão é não usar nomes de arquivos (ou nomes de diretórios) com espaços neles. Se você possui espaços ou caracteres "engraçados" em seus nomes de arquivos (ou nomes de diretórios), precisará fazer um trabalho extra para lidar com isso. (No GNU find, há uma seção inteira na manpágina chamada "ARQUIVOS INCOMUNS", devido a esse problema.) O -0sinalizador xargse -print0a findajuda para lidar com esses problemas. Prometo, no entanto, que você não deseja usar -Rno seu comando de cópia. Isso desfará o que você faz para evitar os diretórios SVN.
Telemachus
0

Suponho que depende do tamanho da sua árvore, mas por que não copiar tudo primeiro e depois aparar as pastas .svn depois:

find /dest-dir -type d -name .svn -exec rm -rf {} \;

?

Steve Folly
fonte
Sem nenhum benchmarking, meu pensamento inicial é que isso é um desperdício duplo de ciclos de CPU: a cópia e a remoção. Pode levar um tempo humano extra para elaborar o findcomando certo , mas você faz isso apenas uma vez. Você pode usar o comando centenas de vezes, depois de acertar.
Telemachus
@Telemachus - é verdade, mas é nisso que os computadores (supostamente são) são bons - fazendo coisas complicadas para que não precisemos! Realmente - que mal há em copiar alguns arquivos apenas para excluí-los logo depois, se isso significa que os comandos que você inventa para fazê-lo são muito simples?
28119 Steve Folly
@ Steve: realmente não há mal nenhum. Na medida do possível, esta é uma boa solução. Segue um princípio que eu gosto: "Faça a coisa mais simples possível que funcione". Por outro lado, viola outro princípio de que gosto ainda mais: "Aprenda suas ferramentas". Eu preferiria aprender a se usar findmelhor, para não precisar fazer isso. Mas você está certo: não há nada realmente errado com esta solução.
Telemachus
@Telemachus: Eu concordo com "Aprenda suas ferramentas". Quando eu comecei, eu tenho certeza que o meu comando find acima teria parecia muito críptica-me então :-)
Steve Folly
0

Não esqueça grep -v

find . | grep -v .svn
Nick Stinemates
fonte
Este comando não faz o que você pensa que está fazendo.
Juan A. Navarro
0

Você também pode fazer o oposto. Copie tudo e exclua as pastas .svn usando o comando abaixo:

find . | grep ".svn" | xargs rm -rf
devXen
fonte