¿Por qué no funciona mi tubería?

¿Por qué no funciona mi tubería?

Estoy intentando crear un script bash que encuentre todos los mp3 en mi carpeta de Descargas y los mueva a una carpeta de música. ¿Por qué no funciona esta línea?

find ./ -type f -name \*.mp3 | mv *.mp3 /home/mitch/Desktop/Music/$ARTIST

Intenté usar una canalización para traducir la información del primer comando al segundo, pero nunca antes había usado una canalización y no sé si lo estoy haciendo mal o si tengo una idea equivocada de para qué se usan. para.

Respuesta1

El mvcomando no usa su entrada estándar, por lo que debe traducir la entrada estándar a un parámetro, y para esto se puede usar xargs:

find ./ -type f -name '*.mp3' | xargs mv -t /home/mitch/Desktop/Music/$ARTIST

Además, puedes utilizar directamente la -execacción de find:

find ./ -type f -name '*.mp3' -exec mv {} /home/mitch/Desktop/Music/$ARTIST ';'

Editar

Como señaló @geirha, el primer comando no funciona si tiene nombres de archivos que contienen espacios. En tal caso debería ser el siguiente

find ./ -type f -name '*.mp3' -print0 | xargs -0 mv -t /home/mitch/Desktop/Music/$ARTIST

Respuesta2

La ventaja de xargs es la expansión de la línea de comando. Si tuviera un comando que devolviera una gran cantidad de texto (o muchos archivos en un solo comando), necesitaría xargs.

Si tuviera varios miles de archivos en un directorio y quisiera ejecutar algún script en esa lista, podría intentar " ./myprogram *", pero si su programa tiene algún límite en el tamaño de un parámetro, podría agotar el búfer expandiendo *. Además, la línea de comando en sí tiene límites, por lo que el comando puede fallar porque el búfer de la línea de comando está desbordado. El uso de xargs evitará el problema.

Por último, -print0 en find colocará delimitadores nulos para espacios en los nombres de archivos devueltos, y la opción -0 en xargs interpretará esos nulos. Leer man xargs.

información relacionada