Mejor manera de extraer una subcadena en bash

1

Tengo una lista de mp3archivos nombrados así:

$artist/$album ($year)/$tracknum $title.mp3

Muchas de estas pistas tienen etiquetas incorrectas o faltantes, que estoy corrigiendo mediante el uso de id3v2y regex porque los nombres de los archivos son correctos. Aquí hay un ejemplo de cómo estoy configurando títulos:

for mp3 in *.mp3; do id3v2 -t "$(echo $mp3 | cut -d. -f1 | cut -d\  -f2-)" "$mp3"; done

(Nota: las citas están ahí porque los títulos a menudo tienen espacios, lo que hace que bash se queje a menos que se usen espacios)

Mi pregunta es esta: ¿hay una mejor manera de extraer una subcadena específica de estos archivos? En el caso de los títulos, no puedo usar grep -osin que también coincidan $tracknumporque muchas pistas tienen números y espacios en los títulos (lo que significa que necesitaría "([0-9a-zA-Z ]+)"mi patrón, que coincide con el nombre de archivo completo antes del .mp3).

Estoy casi seguro de que hay una forma mucho mejor de hacer esto. ¿Esta ahí?

J David Smith
fuente

Respuestas:

1

Si desea extraer el título (y, en caso de que sea útil, el tracknum), debería poder hacerlo así:

read -r tracknum title <<<$(basename "$mp3" .mp3)

Para los otros bits, comenzaría dividiendo el nombre del archivo /para aislar las partes. Por ejemplo:

album_year=$(cut -d/ -f2 <<<"$mp3")
album=${album%\ (*)}
year=${album_year:-5:4}

El último depende del año realmente presente y de cuatro dígitos de largo; si eso no está garantizado, puede hacerlo con una expresión más torpe:

year=${album_year:$((${#album}+2)):$((${#album_year}-${#album}-3}

Además, si no sabe qué tan profunda es la ruta en la album_yearparte, puede extraer el segundo último segmento (es decir, el directorio inmediato del archivo) con:

album_year=$(basename "$(dirname "$mp3")")

O bien, puede dividir la ruta completa en una matriz:

IFS=/ read -ra segments <<<"$mp3"
album_year=${segments[-2]}
rici
fuente
Tuve que invertir la cadena de ruta (es la ruta completa desde /) antes de pasarla a cortar, pero en general fue muy útil.
J David Smith
1
@ J.DavidSmith: Podría haber ajustado el -f2 a la profundidad real :) Agregué otra forma de obtener el segundo último componente de una ruta de archivo.
rici
Si pudiera volver a votar tu respuesta, lo haría.
J David Smith