3

У меня есть ситуация, когда у меня есть некоторые входные файлы, как это:

M2U0001.MPG
M2U0180.MPG

И я хочу запустить команду (в оболочке Bash) для каждого файла с аналогичным именем в каталоге. Мне бы хотелось, чтобы текущее имя файла было задано этой команде в качестве входных данных, а измененная версия имени файла - в качестве выходного файла. Вот пример:

ffmpeg -i M2U0001.MPG M2U0001_fixed.MPG

У меня была идея использовать xargs и sed, но это насколько я понял:

ls -1 *.MPG | xargs -I{} ffmpeg -i {} `echo {} | sed -r 's/[0-9]{2,}/&_fixed/'`

Но это приводит к тому, что исходное имя файла выводится в обе позиции. Я все об этом говорю неправильно?

Я обнаружил, что если я передаю имя файла непосредственно во встроенный фрагмент, то это работает:

echo M2U0001.MPG | sed -r 's/[0-9]{2,}/&_fixed/'

4 ответа4

4

Или в качестве альтернативы:

for i in *.MPG ; do ffmpeg -i $i `basename $i .MPG`_fixed.MPG ; done

Спасибо joshbaptiste за подсказку.

2

поскольку я не должен использовать for i in $(ls) - вывод ls(1) не должен использоваться для синтаксического анализа с помощью сценариев и т. д. из-за разбиения слов, и это распространенная ошибка, которую я вижу в сценариях Bash на своей работе.

В этом случае расширение параметров работает нормально и не подвержено ошибкам разделения слов.

for i in *.MPG; do ffmpeg -i "$i" "${i%%.*}"_fixed.MPG ; done

Ссылка: http://mywiki.wooledge.org/BashPitfalls

2
find . -iname "*.mpg" -exec sh -c "ffmpeg -i {} `echo {} | sed -e 's/\./_fixed\./'`" \;
0

Вот конкретный вариант:

ls -1 src/*.c | xargs -i sh -c "echo;gcc -fpreprocessed -dD -E {} 2>&1 | grep -wi -e one -e two -e three -n | sed 's:^:{}\::'" | cat -s

Список исходных файлов C,

ls -1 src/*.c

передается в xargs, который выполняет препроцессор в дочерней оболочке,

gcc -fpreprocessed -dD -E {} 2>&1

который впоследствии передается в нужную команду grep

grep -wi -e one -e two -e three -n

который затем передается в sed для добавления в каждую строку текущего имени файла:

sed 's:^:{}\::'

Наконец, все повторяющиеся пустые строки свернуты в одну строку с помощью cat:

cat -s

Это работает в системе Red Hat Linux 6, но я предполагаю, что она достаточно общая для других систем * nix.

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