2016-06-19 3 views
2

У меня есть директория с несколькими поддиректорами, которые содержат .flac. Я хочу конвертировать их в .mp3. Имена путей содержат пробелы. Теперь я хочу сделать что-то вроде этогоBatch-process files with find in multiple directories

find . -type f -regex .*.flac -exec ffmpeg -i {} -c:a mp3 -b:a 320k \; 

Но вопрос в том, как я могу использовать {} и заменить flac для mp3 дать FFmpeg имя выходного файла? В bash можно использовать переменную замену ${file%.flac}.mp3, но я не могу применить это здесь. sed - основанные подходы, похоже, не работают с find. Есть ли простое решение?

+1

КПП. quote '* .flac'. – Cyrus

ответ

3

Если вы используете Баш, я бы использовать globstar, который будет расширяться в список всех ваших .flac файлов:

shopt -s globstar nullglob 
for file in **/*.flac; do 
    [[ -f $file ]] || continue 
    out_file=${file%.flac}.mp3 
    ffmpeg # your options here, using "$out_file" 
done 

Проверка [[ -f $file ]] пропускает любые каталоги, которые заканчиваются в .flac. Вероятно, вы можете пропустить это, если у вас их нет.

Я также включил опцию оболочки nullglob, так что шаблон, который не соответствует никаким файлам, не расширяется до нуля (поэтому цикл не будет работать).

+0

Тогда вы заслуживаете мой плюс-один ':)'. –

2

Если вы действительно хотите использовать find (например, вы застряли в прошлом с античной версией Bash и globstar недоступны, поэтому использование решения Tom Fenech не является вариантом), вы должны создать оболочки для замены. Стандартный путь будет:

find . -name '*.flac' -type f -exec sh -c 'ffmpeg -i "$1" -c:a mp3 -b:a 320k "${1%.flac}.mp3"' dummy {} \; 

sh -c будет работать свой первый аргумент, и аргументы подпоследовательности устанавливаются в позиционные параметры , начиная с 0. Вот почему я поставил фиктивный параметр (и я назвал его dummy, но все остальное могло бы сделать).

Обратите внимание, что в find-name необходимо указать аргумент *.flac. По какой-то причине вы отредактировали свое сообщение и заменили предикат -name предикатом -regex: это действительно бесполезно, и вам все равно нужно процитировать аргумент в любом случае.

+0

Невозможно написать 'sh -c 'ffmpeg -i" $ 0 "-c: mp3 -b: a 320k" $ {1% .flac} .mp3 "' {} \;' –

+1

@mona_sax: nope , это не совсем верно, поскольку в этом случае позиционный параметр '$ 1' не задан! может быть, вы имеете в виду: 'sh -c 'ffmpeg -i" $ 0 "-c: mp3 -b: a 320k" $ {0% .flac} .mp3 "' {} \;', и это совершенно верно. –

+1

Ну да! Я имею в виду то, что вы только что указали. :). Я хотел избежать использования фиктивной переменной. Это действительно элегантный лайнер :) +1 –