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. ; -)
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.
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. ; -)
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
. ; -)
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.
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. Este trabalhou para mim:
find -name "*.csv" | xargs cp --parents -t /target
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.
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/
Tags cp