Como cp arquivo e criar diretório, se não existe?

15

Eu quero copiar arquivos modificados em um repositório svn para outro diretório, enquanto mantém sua estrutura de diretórios.

Depois de ler awk e xargs manpage, eu encontrei uma maneira de obter nomes de arquivos alterados como este:

$ svn status -q | awk '{ print $2 }' | xargs -d \n -I '{}' cp '{}' /tmp/xen/

Mas o problema é que desta forma as estruturas de diretórios não são preservadas, eu quero copiar arquivos como este:

./common/superp.c -> /tmp/xen/common/superp.c
./common/m2mgr.c -> /tmp/xen/common/m2mgr.c
./common/page_alloc.c -> /tmp/xen/common/page_alloc.c
./arch/x86/mm.c -> /tmp/xen/arch/x86/mm.c
./arch/x86/mm/shadow/private.h -> /tmp/xen/arch/x86/mm/shadow/private.h

Eu tentei alterar o comando cp para cp '{}' / tmp / xen / '{}' , mas ele disse que nenhum arquivo ou diretório. Existe alguma maneira de fazer o arquivo de cópia cp e criar diretório, se necessário? E por favor, indique se esta cadeia de comando pode ser simplificada. : -)

Obrigado por todas as suas respostas. Como o diretório é um pouco grande, não quero copiar o diretório inteiro usando cp -R ou rsync. A sugestão de CK de usar um tubo de alcatrão é bastante útil.

svn status -q | awk '{ print $2 }' | xargs tar cf -  | (cd /tmp/xen/; tar xvf -)
    
por ZelluX 03.08.2009 / 15:59

7 respostas

12

Algumas reflexões rápidas:

  • Adicionar em um mkdir -p $ (dirname FILE)
  • Você poderia usar um tubo de alcatrão para resolver tudo?

Editar

 tar -cf archive.tar  'svn status -q | awk '{print $2}''

Deve criar um arquivo dos arquivos modificados. Então:

  tar -xf archive.tar -C /tmp/xen

deve colocá-lo onde quiser. Se precisa estar em um passo, isso também é possível.

    
por 03.08.2009 / 16:09
4

O rsync torna a ferramenta bastante simples, geralmente usada para copiar estruturas inteiras de diretórios:

rsync -av /home/source/svn/repo /home/dest/svn/

Isto irá criar o diretório repo e todo o seu conteúdo no diretório / home / dest / svn, assim você terá / home / dest / svn / repo /...

Então, para o seu exemplo:

rsync -rv ./ /tmp/xen/

-a, preservaria os timestamps e seria recursivo entre outras coisas, 'man rsync'.

Atualizar depois de perceber que li a pergunta errada:

Para imitar a estrutura de diretórios (alternativa de tar):

rsync -av --include='*/' --exclude='*' source destination

E, em seguida, para copiar os arquivos antes, digamos, 20 minutos atrás:

find . -type f -mmin -20 -print0 | xargs -0 cp --target-directory /mydestdir/
    
por 03.08.2009 / 16:19
2

Aqui está o one-liner para referência:

svn status -q | awk '{print $2}' | xargs tar -c | tar -xC /tmp/xen

E em inglês:

  • obtenha uma lista de arquivos de interesse com svn status -q , que é canalizada para ...
  • awk que extrai a coluna com os caminhos de arquivos: awk '{print $2}'
  • xargs é usado para fornecer a lista de arquivos ao tar, que, por sua vez, envia um tarball dos arquivos para o stdout: xargs tar -c
  • que é reextraído imediatamente ( -x ) no diretório de destino ( -C path ): tar -xC /tmp/xen
por 18.05.2011 / 14:34
1

Use "dirname" para extrair o caminho "mkdir -p" para criá-lo, algo como:

xargs -d \n -l '{}' mkdir -p \'dirname '{}'\' && cp '{}' /tmp/xen/
    
por 03.08.2009 / 16:09
1

rsync -a não cria novos diretórios mais profundos que em profundidade 1, então rsync é apenas uma solução parcial e por exemplo não é adequada para mim (pesquisei como responder a diretórios rsync em alguma hierarquia remota quando vários diretórios estão faltando) no meio)

Editar: Quer dizer, eu tenho dir fonte: /home/user/projects/homework/1/1.1/ E eu quero rsync para remoto: /home/user/projects/homework/1/1.1/ ... mas o destino ainda não tem diretório / home / user / projects / homework ... e eu não quero transferir outros subdiretórios na máquina de origem que estão em / home / user / projects /

Editar2: Encontrei um jeito, com a opção rsync --relative: O exemplo acima seria assim:

cd / home / projects /; rsync -aR lição de casa / 1 / 1.1 user @ remote: / home / usuário / projects /

    
por 16.11.2010 / 19:32
0

Eu sugeriria o seguinte:

  • copie tudo
  • encontre arquivos não modificados e exclua-os, deixando os arquivos modificados em seus lugares.

A propósito, cp com R flag copia arquivos / pastas recursivamente.

cp -R
    
por 03.08.2009 / 16:09
0
  • crie estrutura de diretório em /tmp/f2 para arquivos em /tmp/f

    $ cd /tmp/f/
    $ find . -type f -exec dirname {} \; | uniq | xargs -I {} mkdir /tmp/f2/{} -p
    
  • copia o arquivo para a nova destinação /tmp/f2/

    $ cd /tmp/f
    $ find . -type f -exec cp  {}  /tmp/f2/{} -aPv \;
    
por 10.09.2013 / 14:08