Shell find и запуск команды, удаление расширения, манипуляция с {}
Нужно вытянуть из mp4 в mp3 звуковую дорожку. В общем работает такое
find . -name "*.mp4" -exec ffmpeg -i {} -b:a 192K -vn {}.mp4 \;
Но хотелось бы очистить (удалить) расширение mp4 а то на выходе, конечно получаю .mp4.mp3
Делал разными способами
find . -name "*.mp4" -exec echo {}#.mp4 \;
find . -name "*.mp4" -exec echo {{}#.mp4} \;
find . -name "*.mp4" -exec echo ${{}#.mp4} \;
Для теста, конечно, заменил команду, чтобы увидеть как будет очищаться расширение, но не получилось. Где моя ошибка?
Ответы (1 шт):
например, так:
$ find -name \*.mp4 -exec sh -c 'echo "вход: $1 выход: ${1%.mp4}.mp3"' -- '{}' \;
вход: ./файл.mp4 выход: ./файл.mp3
обратите внимание, что вторым аргументом программе sh передаётся строка в одинарных кавычках. это чтобы экземпляр оболочки, в котором вы запускаете команду, не пытался обрабатывать встречающиеся в строке $1 и ${1%.mp4}. если надо заключить всё-таки в двойные кавычки, то символ $ надо будет «заэскейпить»: \$.
Где моя ошибка?
find . -name "*.mp4" -exec echo ${{}#.mp4} \;
ход мысли, в общем, правильный — воспользоваться parameter expansion. но:
- программа find этого не умеет, а умеет программа, выполняющая функцию (posix-совместимой) оболочки, которую (программу) и надо явно вызвать (как в моём примере)
как явствует из самого названия («parameter expansion»), в конструкции должен присутствовать параметр (в терминологии стандарта posix — это имя переменной, номер аргумента или спецсимвол).
- так:
${xyz%строка}— можно (обрабатываться будет значение переменнойxyz) - и так:
${1%строка}— можно (обрабатываться будет первый аргумент) - а так:
${./файл.mp4%строка}— нельзя (надеюсь, понятно, откуда появляется строка./файл.mp4— её подставит программа find вместо{}
- так:
- ну и по мелочи:
${параметр#строка}— удалит префикс, а вам надо суффикс:${параметр%строка}