Copie o tipo de arquivo específico mantendo a estrutura da pasta

83

Eu tenho uma estrutura de pastas com vários arquivos * .csv espalhados pelas pastas. Agora quero copiar todos os arquivos * .csv para outro destino, mantendo a estrutura da pasta.

Funciona fazendo:

cp --parents *.csv /target
cp --parents */*.csv" /target
cp --parents */*/*.csv /target
cp --parents */*/*/*.csv /target
...

e assim por diante, mas eu gostaria de fazer isso usando um comando.

    
por Wilfred Hughes 18.07.2013 / 15:39

7 respostas

94

Existe alguma razão pela qual as pessoas resistem a usar o -exec de find? É muito útil.

find . -name '*.csv' -exec cp --parents \{\} /target \;

Conheça suas ferramentas. ; -)

    
por 03.01.2014 / 09:39
34

Você também pode usar rsync para isso.

$ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/

Se você quiser manter diretórios vazios da árvore de fontes, pule a opção --prune-empty-dirs :

$ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/

Se você não quiser links simbólicos, datas de modificação, permissões de arquivo, proprietários, etc., substitua -a por outra combinação de -rlptgoD . ; -)

    
por 18.07.2013 / 17:37
25

Você pode usar localizar e cpio no modo de passagem

find . -name '*.csv' | cpio -pdm  /target

Isso localizará todos os arquivos .csv no diretório atual e abaixo e os copiará para / target mantendo a estrutura de diretórios com base em . .

Se você usar

find /path/to/files -name '*.csv' | cpio -pdm /target

encontrará todo o arquivo em /path/to/files e abaixo e copiá-los para /target/path/to/files e abaixo.

    
por 18.07.2013 / 16:58
18

O comando cp permite vários argumentos de origem:

cp **/*.csv --parents ../target

CAVEAT: estou usando um glob recursivo aqui; essa é a opção globstar no Bash 4+ e ksh e é suportada por padrão em zsh . Globs recursivas não correspondem a arquivos e pastas ocultos, e as algumas implementações seguem links simbólicos, enquanto outras não .

Se o seu shell não suporta globs recursivas, ou se você preferir não usá-las, você pode fazer o seguinte:

  • *.csv */*.csv */*/*.csv */*/*/*.csv - isso é muito redundante e requer saber o quão profunda é a sua estrutura de diretórios.
  • $(find . -name '*.csv') - Este irá corresponder aos arquivos e pastas ocultos. find também suporta especificar se os links simbólicos são ou não seguidos, o que pode ser útil.
por 29.05.2014 / 21:37
10

Este trabalhou para mim:

find -name "*.csv" | xargs cp --parents -t /target

    
por 06.10.2016 / 22:23
8

Supondo que você queira replicar essa estrutura de ./source para ./destination :

cd source
find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)

Estou preparado para contar isso como uma linha, o cd source sendo um shell embutido.

    
por 18.07.2013 / 16:26
7

A partir da página de manual de rsync :

-R, --relative

Use relative paths. This means that the full path names specified on the command line are sent to the server rather than just the last parts of the filenames. This is particularly useful when you want to send several different directories at the same time. For example, if you used this command:

rsync -av /foo/bar/baz.c remote:/tmp/

... this would create a file named baz.c in /tmp/ on the remote machine. If instead you used

rsync -avR /foo/bar/baz.c remote:/tmp/

then a file named /tmp/foo/bar/baz.c would be created on the remote machine, preserving its full path. These extra path elements are called "implied directories" (i.e. the "foo" and the "foo/bar" directories in the above example).

Então, isso também funcionaria:

rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/
    
por 24.09.2016 / 02:37

Tags