2013-08-22 2 views
1

У меня есть куча AVI, которую я бы хотел переработать в h264 MKVs. Команда, которую я пытаюсь использовать, это:Использование xargs и sed для обработки avi-файлов

find . -name "*.avi" | xargs -I '{}' ffmpeg -i {} -vcodec libx264 `echo {} | sed 's/avi/mkv/'` 

Однако, он не работает должным образом. Добавление -t в xargs показывает, что команда является прогон (предоставляется каталог с file1.avi)

ffmpeg ./file1.avi -vcodec libx264 ./file1.avi 

Я не знаю, почему СЭД команда не получает обрабатываются корректно. ffmpeg терпит неудачу, поскольку по умолчанию он не перезаписывается.

AVI все находятся в подкаталогах, поэтому я не хочу делать цикл for для каждой вложенной папки и find/xargs будет гораздо лучшим решением. Кроме того, я действительно не хочу переименовывать все после того, как это будет сделано.

ответ

2

Причина, по которой это не работает, потому что все между ` ` выполнено до исполнения xargs. Но если вы укажете его в ' ', то он будет передан правильно, но xargs не собирается разбирать и расширять его.

Но вы можете подключиться к функции bash!

convertFile() { 
    while read -r filename; do 
     newFilename="${filename:0:-3}mkv" 
     ffmpeg "$filename" -vcodec libx264 "$newFilename" 
    done 
} 

find . -name "*.avi" | convertFile 

Пожалуйста, обратите внимание, что вместо sed я использую Баш со строками. Причиной этого является то, что ваш файл может иногда содержать Avi слово внутри, как грAviти. Вот почему был использован более отказоустойчивый способ.

+0

Хотя мне нравятся примеры одного лайнера, я собираюсь сказать, что мне это нравится больше. Только потому, что он напоминает мне, что я могу предварительно определить функции в ~/.bashrc для повторных задач. – tscheez

0

Вы можете использовать следующую команду вместо:

find *.avi | awk '{print "\""$0"\"", "-vodec libx264","\""$0"\""}' | sed 's/\(.*\)avi\"$/\1mkv\"/g' | xargs ffmpeg -i 

Конечно, это имеет много экранирующих символов. Это не сценарий, это из командной строки ...

+0

Это не сработает, если файл называется '' miyavi.avi''. Также это не работает для файлов с пробелами в их имени. –

+0

ОК, спасибо за указание. Я отредактировал свой ответ. – iamauser

+0

Можете ли вы указать, почему у меня все еще есть отрицательный голос? – iamauser

1
find *.avi | while read f; do 
    ffmpeg "$f" -vcodec libx264 "${f%.avi}.mkv" 
done 

и я разделить линии, чтобы не пугать людей, но в реальной жизни это было бы

find *.avi|while read f;do ffmpeg "$f" -vcodec libx264 "${f%.avi}.mkv"; done 

, потому что это односторонняя территория.

Смежные вопросы