1

У меня есть список файлов mp3 названный так:

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

Многие из этих треков имеют неправильные или отсутствующие теги, которые я исправляю с помощью id3v2 и regex, потому что имена файлов все правильные. Вот пример того, как я устанавливаю заголовки:

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

(Примечание: здесь есть кавычки, потому что заголовки часто имеют пробелы, что приводит к тому, что bash будет жаловаться, если они не используются)

У меня такой вопрос: есть ли лучший способ извлечь определенную подстроку из этих файлов? В случае с заголовками я не могу использовать grep -o без совпадения с $tracknum потому что во многих дорожках есть номера и пробелы в заголовках (это означает, что мне нужно "([0-9a-zA-Z ]+)" для моего шаблона, который соответствует всему имени файла перед .mp3).

Я почти уверен, что есть гораздо лучший способ сделать это. Есть?

1 ответ1

1

Если вы хотите извлечь заголовок (и, если он полезен, tracknum), вы должны сделать это следующим образом:

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

Что касается других битов, я бы начал с разделения имени файла на / чтобы изолировать части. Например:

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

Последний зависит от фактического года и имеет четыре цифры в длину; если это не гарантировано, вы можете сделать это, используя более неуклюжее выражение:

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

Кроме того, если вы не знаете, насколько глубоко в пути находится часть album_year , вы можете извлечь второй последний сегмент (то есть непосредственный каталог файла) с помощью:

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

Или вы можете разбить весь путь на массив:

IFS=/ read -ra segments <<<"$mp3"
album_year=${segments[-2]}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .