recursivamente copiar apenas imagens e preservar caminho

5

Estou trabalhando em uma migração de website. Eu tenho um arranhão do site, com todos os arquivos e estrutura de diretórios como você os veria no URL. Eu quero puxar todas as imagens, mantendo a estrutura de diretórios e copiá-los para um novo local.

Por exemplo, se eu tiver

/content1/index.php
/content1/page2.php
/content1/images/image1.jpg
/content1/images/image2.jpg
/content1/background/spacer.gif
/content1/background/background.gif
/content2/index.php
/content2/images/image3.jpg
/content2/background/spacer.gif
/content2/background/background.gif

Então eu quero

/content1/images/image1.jpg
/content1/images/image2.jpg
/content1/background/spacer.gif
/content1/background/background.gif
/content2/images/image3.jpg
/content2/background/spacer.gif
/content2/background/background.gif

Eu posso usar o comando find para obter uma lista de apenas arquivos de imagem, mas não sei como manipular cada arquivo enquanto preservo o caminho do diretório para ele.

Eu poderia fazer uma cópia de todo o diretório e, em seguida, excluir recursivamente qualquer arquivo sem imagem, mas agora que defini esse problema antes de mim, acho valer a pena saber como fazer isso, caso eu realmente faça isso. precisa fazer isso mais tarde.

    
por user394 31.08.2011 / 17:37

3 respostas

8

Tente este comando ( find e cp com --parent opção):

find /source -regextype posix-extended -regex '.*(gif|jpg)' \
    -exec cp --parents {} /dest \; -print
    
por 31.08.2011 / 18:25
2

Use pax (ou um dos seus antecessores, cpio ou tar) no modo de cópia. Diga para copiar apenas os arquivos desejados ( .jpg ou .gif ). A sintaxe é uma pequena rotatória: a opção -s especifica como renomear arquivos; renomear um arquivo para um nome vazio significa que ele não será copiado e, como a primeira correspondência se aplica, para excluir a maioria dos arquivos, o truque é renomear os arquivos que você deseja incluir para si mesmo e excluir o restante. Os diretórios não serão copiados dessa forma, mas se pax copiar foo/bar/qux.jpg , ele criará foo e foo/bar no destino, se necessário, e o pax recorrerá mesmo dentro dos diretórios excluídos.

pax -rw -pp -s '!\.gif$!&!' -s '!\.jpg$!&!' -s '!.*!!' /content* /destination

Você também pode usar o rsync para executar a cópia, mas é mais desajeitado. Como o rsync não copia diretórios excluídos, você precisa incluir todos os diretórios e remover os diretórios vazios ou gerar a lista de diretórios a serem copiados. Consulte esta resposta para obter explicações.

rsync -a --include='*.gif' --include='*.jpg' --include='*/' \
      --exclude='*' /content* /destination
    
por 01.09.2011 / 01:41
0

Supondo que queremos copiar todos os arquivos * .conf de / etc / to / tmp /, eu deveria fazer:

tar c $(find /etc/ -name '*.conf') | tar xv -C /tmp

Como funciona:

  1. crie uma lista de arquivos a serem copiados por meio de $(find ...)
  2. tar c cria um novo arquivo tar e passa para stdout
  3. | canaliza esse arquivo para outro processo tar para descompactar
  4. tar xv arquivo de extrato detalhado lido de stdin, mas com o diretório alterado para /tmp (destino).

Este método não funcionará corretamente com arquivos com espaços nele. Para corrigir, você pode gerar uma lista de arquivos e passar o primeiro comando tar pela opção -T.

    
por 02.09.2011 / 23:54