id3v2 usado recursivamente en la línea de command?

Tratando de limpiar mis tags id3 y me encanta id3v2 en la command-line, pero solo lo he usado con un comodín * .mp3 y quiero explorar si hay una manera de usarlo recursivamente para poder agrupar todos mis MP3. No parece haber una opción para usarlo recursivamente.

Estoy bastante seguro de que todos ustedes, increíbles compañeros de línea de command, saben de una manera dulce de hacer esto, pero todavía estoy aprendiendo cómo hacerlo …

Aquí están los commands a los que tengo un alias para forzarlo brutalmente:

id3v2 --remove-frame "COMM" *.mp3 id3v2 --remove-frame "PRIV" *.mp3 id3v2 -s *.mp3 

Entonces, ¿hay alguna manera de hacerlo de forma recursiva, así que puedo ejecutarlo en la raíz de mi carpeta de música? Puntos de gracia para: include otros types de files de audio y contraer los tres commands anteriores en un command uber (puedo hacerlo con los commands ; entre commands … ¿no?)

Debería poder hacer esto en una sola línea, con algo como esto:

 find . -name '*.mp3' -execdir id3v2 --remove-frame "COMM" '{}' \; -execdir id3v2 --remove-frame "PRIV" '{}' \; -execdir id3v2 -s '{}' \; 

Los {} se sustituyen por la coincidencia de nombre de file actual. Ponerlos entre comillas ( '' ) los protege del caparazón. El -execdir ejecuta hasta que llega a un punto y coma, pero el punto y coma ( ; ) necesita escapingse del intérprete de commands, de ahí el uso de la barra invertida ( \ ). Todo esto se describe en la página de find hombre :

 -exec command ; Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of `;' is encountenetworking. The string `{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. -execdir command {} + Like -exec, but the specified command is run from the subdirec‐ tory containing the matched file, which is not normally the directory in which you started find. This a much more secure method for invoking commands... 

Ya que parece que es un poco nuevo en esto, una advertencia : como siempre con commands de shell complejos, ejecútelos con cuidado e intente primero en un directory de testing para asegurarse de que comprende lo que va a suceder. ¡Con un gran poder viene una gran responsabilidad!

Una solución rápida es recorrer todas las subcarpetas y procesar todos los files en ella:

 find . -type d | while IFS= read -rd; do cd "${d}" id3v2 --remove-frame "COMM" *.mp3 id3v2 --remove-frame "PRIV" *.mp3 id3v2 -s *.mp3 cd - done 

No uso id3v2 así que no puedo estar seguro, pero hay muchas posibilidades de que puedas combinar todos tus commands en uno solo:

 id3v2 --remove-frame "COMM" --remove-frame "PRIV" -s *.mp3 

Para ejecutar este command en files MP3 en subdirectorys también, ejecuta

 id3v2 --remove-frame "COMM" --remove-frame "PRIV" -s **/*.mp3 

**/*.mp3 coincide con los files .mp3 en el directory actual y sus subdirectorys recursivamente. Si su shell es zsh, **/ funciona de la caja. Si su shell es bash ≥4, debe ejecutar shopt -s globstar primero (ponga esta línea en su ~/.bashrc ). En ksh, necesita ejecutar set -o globstar (ponerlo en ~/.kshrc ). Si tiene otro shell, o si este bash falla con un post que le dice que la línea de command es demasiado grande, deberá usar el método de find continuación (con variantes como las que se dan en otras respuestas).

Una forma más compleja, pero más flexible y más portátil de actuar sobre los files en un directory y sus subdirectorys recursivamente es el command find :

 find . -type f -name '*.mp3' -exec id3v2 --remove-frame "COMM" --remove-frame "PRIV" -s {} + 

El command after -exec se ejecuta con el bit {} + al final reemplazado por las routes a los files coincidentes. Si necesita ejecutar múltiples commands id3v2 , use múltiples directivas -exec :

 find . -type f -name '*.mp3' -exec id3v2 --remove-frame "COMM" {} + -exec id3v2 --remove-frame "PRIV" {} + -exec id3v2 -s {} +