¿Cómo puedo buscar archivos en todos los subdirectorios usando el shell y luego copiar esos archivos?

8

¿Cómo puedo encontrar solo los archivos * .mp3 con un comando recursivo como ls -R *.mp3en un directorio que contiene varios subdirectorios y, al final, copiar estos archivos en un directorio que yo elija.

Gracias por su apoyo.

V 3 L 3 N 0
fuente

Respuestas:

14

El comando es:

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

Alternativa:

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

Ejemplo:

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 más información:

man find
hytromo
fuente
Los jueces también aceptarían:find /path/to/dir/ -name '*.c' | xargs cp -t /target/
Oli
Soy uno de los jueces y niego esta solución 8-) Gracias por el comentario, lo
agregaré
1
xargsNormalmente es mucho más rápido. Acabo de ejecutar una prueba rápida aquí para encontrar una carga de archivos c y ejecutarlos ls -len ellos. Son 0m2.420s para xargsy 0m25.494s para -exec... Claramente en este caso la cpoperación tomará la mayor parte del tiempo, por lo que probablemente no importe, pero vale la pena tenerlo en cuenta.
Oli
Recomendaría agregar el -n`` switch to the comando cp` para evitar sobrescribir en el caso de nombres duplicados (o escribir un script que busque duplicados antes de copiar y renombrar el objetivo según sea necesario)
Elder Geek
2

También hay otra forma de hacerlo que creo que se adaptará perfectamente a su propósito. Puede combinarse findcon un whilebucle y ni siquiera necesita usar ninguno execo ninguno xargs. Si, por ejemplo, quisiera copiar su mp3sarchivo de descarga a su carpeta de música, usaría el siguiente script, que he usado muchas veces.

Puede modificarlo como desee cambiando los directorios que findbusca y coloca los archivos resultantes; si no se indica ningún directorio, findbuscará en toda la carpeta de inicio. También puede cambiar cpa mvu otros comandos. ¡Es bastante rápido, ya que lo acabo de probar con 3945 .jpgarchivos! Cópielo en un editor de texto, guárdelo y luego hágalo ejecutable ejecutando 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

En este wiki Bash señalado se muestra lo útil que es combinar el whilebucle y los readcomandos para procesar la salida del findcomando; y la forma en que lo he hecho asegura que el script no se rompa si se encuentra con nombres de archivos con espacios u otros caracteres inesperados o especiales.

Para obtener información más general sobre el findcomando, ingrese en el terminal man findo consulte las páginas de manual de Ubuntu en línea . Para una gran introducción al uso de find, vea también este artículo .


fuente
no es find ~/Downloads -type f -iname '*.mp3' | while read mp3file; do cp "$mp3file" ~/Music; donemás simple?
steabert
Mi método representa las mejores prácticas y evita que el script se rompa, como se señaló en el enlace que cité.
ah, ya veo, eso se encarga de manejar caracteres especiales, gracias por el enlace :)
steabert
Recomendaría agregar el -n`` switch to the comando cp` para evitar sobrescribir en el caso de nombres duplicados (o escribir un script que busque duplicados antes de copiar y renombrar el objetivo según sea necesario)
Elder Geek