Melhor maneira de extrair uma substring no bash

1

Eu tenho uma lista de mp3 arquivos assim chamados:

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

Muitas dessas faixas têm tags incorretas ou ausentes, que estou corrigindo com o uso de id3v2 e regex porque o arquivo os nomes estão todos corretos. Aqui está um exemplo de como estou definindo títulos:

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

(Nota: há citações porque os títulos geralmente têm espaços, o que faz com que o bash reclame a menos que espaços sejam usados)

Minha pergunta é: existe uma maneira melhor de extrair uma substring específica desses arquivos? No caso dos títulos, não posso usar grep -o sem corresponder também a $tracknum porque muitas faixas têm números e espaços nos títulos (o que significa que eu precisaria de "([0-9a-zA-Z ]+)" para meu padrão, que corresponde ao nome do arquivo inteiro antes do .mp3 ).

Estou quase certo de que há uma maneira muito melhor de fazer isso. Existe?

    
por J David Smith 05.08.2013 / 15:55

1 resposta

1

Se você quiser extrair o título (e, caso seja útil, o tracknum), você deve ser capaz de fazer assim:

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

Para os outros bits, eu começaria dividindo o nome do arquivo por / para isolar as partes. Por exemplo:

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

O último depende do ano realmente presente e quatro dígitos; se isso não for garantido, você poderá fazê-lo usando uma expressão mais desajeitada:

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

Além disso, se você não sabe em que profundidade está o caminho da parte album_year , você pode extrair o segundo último segmento (ou seja, o diretório imediato do arquivo) com:

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

Ou você pode dividir o caminho inteiro em uma matriz:

IFS=/ read -ra segments <<<"$mp3"
album_year=${segments[-2]}
    
por 05.08.2013 / 19:46