Ha pasado un tiempo desde que lo he usado make
, así que tengan paciencia conmigo ...
Tengo un directorio flac
, que contiene archivos .FLAC. Tengo un directorio correspondiente que mp3
contiene archivos MP3. Si un archivo FLAC es más nuevo que el archivo MP3 correspondiente (o el archivo MP3 correspondiente no existe), entonces quiero ejecutar un montón de comandos para convertir el archivo FLAC en un archivo MP3 y copiar las etiquetas.
El truco: necesito buscar en el flac
directorio de forma recursiva y crear los subdirectorios correspondientes en el mp3
directorio. Los directorios y archivos pueden tener espacios en los nombres y se nombran en UTF-8.
Y quiero usarlo make
para conducir esto.
make
está más cerca de implementarlo que de lo básicobash
.sh
script que recorre la lista de archivos flac (find | while read flacname
), hace un amp3name
partir de eso, ejecuta "mkdir -p" en eldirname "$mp3name"
, y luego,if [ "$flacfile" -nt "$mp3file"]
convierte"$flacname"
en"$mp3name"
no es realmente mágico. La única característica que realmente está perdiendo en comparación con unamake
solución basada es la posibilidad de ejecutarN
procesos de conversión de archivos en paralelo conmake -jN
.make
y tener espacios en los nombres de los archivos son requisitos contradictorios. Utilice una herramienta adecuada para el dominio del problema.Respuestas:
Intentaría algo en esta línea
Un par de notas rápidas para
make
principiantes:@
frente de los comandos evita que semake
imprima el comando antes de ejecutarlo.$(@D)
es la parte del directorio del nombre del archivo de destino ($@
)Incluso si esto debería manejar todos los caracteres UTF-8 y demás, fallará en los espacios en los nombres de archivos o directorios, ya que
make
usa espacios para separar cosas en los archivos MAKE y no conozco una forma de evitar eso. Entonces eso te deja con solo un script de shell, me temo: - /fuente
vpath
. Debo estudiar eso uno de estos días.find
para obtener los nombres de forma recursiva ...make -jN
. ParaN
utilizar el número de conversiones quemake
deben ejecutarse en paralelo. Precaución: Ejecutarmake -j
sin unN
iniciará todos los procesos de conversión a la vez en paralelo, lo que podría ser equivalente a una bomba de horquilla..PHONY: all
línea le dice a make que la receta para elall
objetivo se ejecutará incluso si hay un archivo llamadoall
más nuevo que todos los$(MP3_FILES)
.Puede definir su propia función comodín recursiva como esta:
El primer parámetro (
$1
) es una lista de directorios y el segundo ($2
) es una lista de patrones que desea hacer coincidir.Ejemplos:
Para encontrar todos los archivos C en el directorio actual:
Para encontrar todos los archivos
.c
y.h
ensrc
:Esta función se basa en la implementación de este artículo , con algunas mejoras.
fuente
make
es un Turing Tar Pit (ver aquí: yosefk.com/blog/fun-at-the-turing-tar-pit.html ). Ni siquiera es tan difícil, pero hay que leer esto: gnu.org/software/make/manual/html_node/Call-Function.html y luego "comprender la recurrencia". USTED tuvo que escribir esto de forma recursiva, en el sentido literal; no es la comprensión cotidiana de "incluir automáticamente cosas de subdirectorios". Es RECURRENCIA real. Pero recuerde: "Para comprender la recurrencia, debe comprender la recurrencia".FWIW, he usado algo como esto en un Makefile :
El ejemplo anterior buscará en el directorio actual ( '.' ) Todos los "archivos sin formato" ( '-type f' ) y establecerá la
RECURSIVE_MANIFEST
variable make para cada archivo que encuentre. A continuación, puede utilizar sustituciones de patrones para reducir esta lista o, alternativamente, proporcionar más argumentos en find para reducir lo que devuelve. Consulte la página de manual para encontrar .fuente
Mi solución se basa en la anterior, usa en
sed
lugar depatsubst
destrozar la salida defind
Y escapar de los espacios.Pasando de flac / a ogg /
Advertencias:
fuente
Aquí hay un script de Python que pirateé rápidamente para resolver el problema original: mantener una copia comprimida de una biblioteca de música. El script convertirá archivos .m4a (se supone que son ALAC) al formato AAC, a menos que el archivo AAC ya exista y sea más reciente que el archivo ALAC. Los archivos MP3 de la biblioteca se vincularán, ya que ya están comprimidos.
Solo tenga cuidado de que abortar el script (ctrl-c ) dejará un archivo a medio convertir.
Originalmente también quería escribir un Makefile para manejar esto, pero dado que no puede manejar espacios en los nombres de archivo (ver la respuesta aceptada) y porque escribir un script bash está garantizado para ponerme en un mundo de dolor, Python lo es. Es bastante sencillo y corto, por lo que debería ser fácil de ajustar a sus necesidades.
Por supuesto, esto se puede mejorar para realizar la codificación en paralelo. Eso se deja como ejercicio para el lector ;-)
fuente
Si está usando Bash 4.x, puede usar una nueva opción de globbing , por ejemplo:
Este tipo de comodín recursivo puede encontrar todos los archivos de su interés ( .flac , .mp3 o lo que sea). O
fuente
**
no funcionará, porque el globbing extendido es una cosa bash / zsh.