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

15

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

Depois de ler a página de manual awk e xargs, encontro uma maneira de alterar os nomes de arquivos como este:

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

Mas o problema é que, dessa maneira, as estruturas de diretório não são preservadas, desejo 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

Tentei alterar o comando cp para cp '{}' / tmp / xen / '{}', mas não havia esse arquivo ou diretório. Existe alguma maneira de criar um arquivo de cópia de cp e criar um diretório, se necessário? E, por favor, indique se essa cadeia de comandos 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 -)
ZelluX
fonte

Respostas:

12

Par de pensamentos rápidos:

  • Adicionar 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 morto dos arquivos modificados. Então:

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

deve colocá-lo onde quiser. Se precisar estar em uma etapa, também é possível.

CK.
fonte
4

O rsync simplifica bastante, é a ferramenta que geralmente uso para copiar estruturas de diretórios inteiras:

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

Isso 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 você exemplo:

rsync -rv ./ /tmp/xen/

-a, preservaria carimbos de data e hora 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 ao tar):

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

E depois copiar os arquivos antes de dizer há 20 minutos:

find . -type f -mmin -20 -print0 | xargs -0 cp --target-directory /mydestdir/
Kyle Brandt
fonte
Essa é a óbvia, mas isso sincronizará tudo, não apenas os arquivos modificados, certo?
CK.
oops, perdi isso #
226 Kyle Brandt
2

Aqui está uma linha 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 seu interesse svn status -q, que são canalizados para ...
  • awk que extrai a coluna com os caminhos de arquivo: awk '{print $2}'
  • xargs é usado para fornecer a lista de arquivos para tar, que por sua vez envia um tarball dos arquivos para stdout: xargs tar -c
  • que é extraído imediatamente ( -x) para o diretório de destino ( -C path):tar -xC /tmp/xen
Tim Abell
fonte
1

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

xargs -d \\n -l '{}' mkdir -p \`dirname '{}'\` && cp '{}' /tmp/xen/
wazoox
fonte
1

O rsync -a não cria novos diretórios com mais profundidade do que a profundidade 1, portanto, o rsync é apenas uma solução parcial e, por exemplo, não é adequado para mim (pesquisei no Google uma resposta sobre como rsync diretórios para alguma hierarquia remota quando vários diretórios estão ausentes no meio )

Edit: Quero dizer, eu tenho dir de origem: /home/user/projects/homework/1/1.1/ E quero sincronizá-lo remotamente: /home/user/projects/homework/1/1.1/ ... mas destino ainda não possui o diretório / home / user / projects / homework ... e não quero transferir outros subdiretórios na máquina de origem que estão em / home / user / projects /

Edit2: Encontrou uma maneira, com a opção rsync --relative: O exemplo acima seria assim:

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

zimon
fonte
0

Eu sugiro o seguinte:

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

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

cp -R
Karolis T.
fonte
0
  • construir estrutura de diretório /tmp/f2para arquivos em/tmp/f

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

    $ cd /tmp/f
    $ find . -type f -exec cp  {}  /tmp/f2/{} -aPv \;
    
ren8zhu
fonte