将 sed 与 xargs 结合使用以获取源文件名和输出文件名

将 sed 与 xargs 结合使用以获取源文件名和输出文件名

我遇到过这样的情况,有一些输入文件:

M2U0001.MPG
M2U0180.MPG

我想要对目录中每个名称相似的文件运行一个命令(在 Bash shell 中)。我希望将当前文件名作为输入提供给此命令,并将文件名的修改版本作为输出文件。以下是示例:

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/'

答案1

或者:

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

感谢约什巴蒂斯特为了暗示

答案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

答案3

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

答案4

以下是一个具体的变化:

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,后者在子 shell 中执行预处理器,

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 系统来说足够通用。

相关内容