Como posso procurar arquivos em todos os subdiretórios usando o shell e copiá-los?

8

Como posso encontrar apenas os arquivos * .mp3 com um comando recursivo, como ls -R *.mp3em um diretório que contém vários subdiretórios e, no final, copiá-los em um diretório que eu escolher.

Obrigado por seu apoio.

V 3 L 3 N 0
fonte

Respostas:

14

O comando é:

find /path/to/directory -name "*.mp3" -exec cp {} /some/other/dir/ \;

Alternativa:

find /path/to/dir/ -name '*.mp3' | xargs cp -t /target/

Exemplo:

alex@MaD-pc:~/test$ ls
1  2  3
alex@MaD-pc:~/test$ ls 1 2 3
1:
1.txt  2.mp3  3.txt

2:
4.txt  5.mp3  6.txt

3:
alex@MaD-pc:~/test$ find . -name "*.mp3" -exec cp {} 3/ \;
alex@MaD-pc:~/test$ ls 3
2.mp3  5.mp3

Para maiores informações:

man find
hytromo
fonte
Os juízes também aceitariam:find /path/to/dir/ -name '*.c' | xargs cp -t /target/
Oli
Eu sou um dos juízes e eu negar esta solução 8-) Obrigado pelo comentário, vou adicioná-lo :)
hytromo
1
xargsnormalmente é muito mais rápido. Acabei de executar um teste rápido aqui, encontrando uma carga de arquivos c e executá ls -l-los. São 0m2.420s para xargse 0m25.494s para -exec... Claramente, neste caso, a cpoperação levará a maior parte do tempo, portanto provavelmente não importa, mas vale a pena observar.
Oli
Eu recomendaria adicionando o -n`` switch to the comando cp` para evitar sobrescrever no caso de nomes duplicados (ou escrever um script que verifica a existência de duplicatas antes de copiar e mudar o nome do alvo, se necessário)
Elder Geek
2

Há também outra maneira de fazer isso, que eu acho que se adequará perfeitamente ao seu propósito. Você pode combinar findcom um whileloop e nem precisar usar um execou xargstodos. Se, por exemplo, você quiser copiar o arquivo mp3sda sua pasta de download para a pasta de músicas, use o script a seguir, que eu usei várias vezes.

Você pode modificá-lo como quiser, alterando os diretórios que findpesquisam e colocam os arquivos resultantes; se nenhum diretório for indicado, findprocurará na pasta pessoal inteira. Você também pode alterar cppara mvou outros comandos. É bem rápido, pois acabei de testá-lo com 3945 .jpgarquivos! Copie-o para um editor de texto, salve-o e torne-o executável executando chmod +x myscript.

#!/bin/bash
# a script to recursively find and copy files to a desired location
find ~/Downloads -type f -iname '*.mp3' -print0 |
while IFS= read -r -d '' f; 
do cp -- "$f" ~/Music ;
done

Neste notável wiki do Bash , é mostrado como é útil combinar o whileloop e os readcomandos para processar a saída do findcomando; e da maneira que fiz isso, garante que o script não seja interrompido se encontrar nomes de arquivos com espaços ou outros caracteres inesperados ou especiais.

Para informações mais gerais sobre o findcomando, entre no terminal man findou consulte as páginas de manual do Ubuntu online . Para uma ótima introdução ao uso do find, consulte este artigo também.


fonte
não é find ~/Downloads -type f -iname '*.mp3' | while read mp3file; do cp "$mp3file" ~/Music; donemais simples?
Steabert
Meu método representa as melhores práticas e evita a quebra do script, conforme observado no link que citei.
ah, eu vejo, que cuida de lidar com caracteres especiais, obrigado pelo link :)
steabert
Eu recomendaria adicionando o -n`` switch to the comando cp` para evitar sobrescrever no caso de nomes duplicados (ou escrever um script que verifica a existência de duplicatas antes de copiar e mudar o nome do alvo, se necessário)
Elder Geek