Пакетная обработка файлов с поиском в нескольких каталогах
У меня есть каталог с несколькими подкаталогами, которые содержат .flac
файлы. Я хочу конвертировать их в пакетном режиме .mp3
, Имена путей содержат пробелы. Теперь я хочу сделать что-то вроде этого
find . -type f -regex .*.flac -exec ffmpeg -i {} -c:a mp3 -b:a 320k \;
Но вопрос в том, как я могу использовать {}
и заменить flac
за mp3
дать ffmpeg имя выходного файла? В bash можно использовать подстановку переменных ${file%.flac}.mp3
, но я не могу применить это здесь. sed
подходы, по-видимому, не работают с find
или. Есть ли простое решение для этого?
2 ответа
Если вы используете Bash, я бы использовал 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
опция оболочки, так что шаблон, который не соответствует ни одному файлу, расширяется до нуля (поэтому цикл не будет работать).
Если вы действительно хотите использовать find
(Например, вы застряли в прошлом с античной версией Bash и globstar
недоступен - так что использование решения Тома Фенека не вариант), вам нужно создать оболочку для замены. Стандартный способ будет:
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
"s -name
, Аргумент *.flac
нужно процитировать. По какой-то причине вы отредактировали свой пост и заменили -name
предикат с -regex
Предикат: это действительно бесполезно, и вам все равно нужно процитировать аргумент в любом случае.