2

Я преобразовал весь блок в моей музыкальной библиотеке в mp3, чтобы перенести блок на внешний диск. Я использовал dbpoweramp в Windows, и я почти уверен, что он конвертировал их все, но когда я проснулся этим утром, нетбук был перезапущен.

Поэтому я составил список со всей моей музыкой и использовал сортировку по алфавиту. Итак, у меня есть что-то вроде этого:

~/music/a/a.flac
~/music/a/a.mp3
~/music/a/b.flac
~/music/a/b.mp3
~/music/b/a.mp3
~/music/b/b.mp3
~/music/c/a.flac
~/music/c/a.mp3

Обратите внимание, что у меня есть каталог только с mp3, так как не вся моя библиотека была flac.

Что мне нужно, так это bash-скрипт, который будет проверять, чтобы все строки, заканчивающиеся на .flac, имели прямую линию под ними, такую же, за исключением того, что она заканчивалась на .mp3.

Как бы я этого добился, и если бы вы могли объяснить, что делает сценарий, это тоже было бы здорово.

Я полагаю, что очень важно показать все строки, заканчивающиеся на .flac, которые НЕ имеют соответствующего .mp3, так как они должны быть преобразованы до сих пор.

3 ответа3

2
awk '
    root && $0 != root ".mp3" {printf("%d: %s.flac\n", line, root)}
    /.flac$/ {
        root=$0
        sub(/.flac$/, "", root)
        line = NR
        next
    }
    { root = "" }
' filename

Как это работает?

Начиная со строки, начинающейся с /.flac$/ , и заканчивая строкой, заканчивающейся на «.flac», создайте переменную с именем root содержащую строку без расширения. Сохраняет текущий номер строки. Перейдите к следующей строке, чтобы избежать удаления только что установленной корневой переменной.

Собираюсь на первую строчку. Это выражение root && $0 != root ".mp3" означает: root не пуст И текущая строка ($0) не равна значению корневой переменной плюс ".mp3". Если это выражение имеет значение true, то текущая строка не является файлом MP3, соответствующим предыдущему файлу FLAC.

Последняя строка стирает значение корневой переменной. Эта часть скрипта достигается только в том случае, если текущая строка не является файлом FLAC, поэтому мы не хотим проводить сравнение со следующей строкой.

1

Можно также использовать find.

С использованием цикла while после find:

find . -name '*.flac' | while read file ; do test -f `dirname $file`/`basename $file .flac`.mp3 && echo $file; done

С использованием (много) подоболочек:

find . -name '*.flac' -exec sh -c 'test -f `echo {} |sed s/\.flac$/.mp3/` && echo {}' \;
1

Я нашел другой способ сделать это, используя diff, но пока не превратил его в скрипт bash. Я отправлю сюда, если найду способ сделать это.

Гленн написал отличный сценарий, который работает, но вот как я это сделал.

Я сделал два отсортированных файла, один с .flac и один с .mp3 с find ~/music -name *.flac | sort > ~/documents/flac и find ~/music -name *.mp3 | sort > ~/documents/mp3

Затем я удалил расширения в VIM

vim ~/documents/flac
:%s/.....$//
:w
:e ~/documents/mp3
:%s/....$//
:wq

А потом я сделал diff ~/documents/mp3 ~/documents/flac | grep '>' который ничего не показал бы, если бы все было сделано правильно, и показал бы мне строки флагов, у которых не было mp3.

Я почти уверен, что получу это в один или несколько строк, но ответ Гленна отлично сработал с файлом, который у меня был.

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