如何在 xargs 中同时使用两个参数?

kis*_*rgy 20 bash command-line xargs command-line-arguments

我需要转换视频,但我不知道它们在哪里,所以我需要find它们。我怎么能放弃的结果和输出文件名的FFmpegxargs

我已经发现我可以用这个命令构造两个参数:

find . -iname "*.mov" -printf "%p %f\n"
Run Code Online (Sandbox Code Playgroud)

我在xargs手册中找不到任何相关内容。我想要这样的东西:

find . -iname "*.mov" -printf "%p %f\n" | xargs ffmpeg -i {param1} -f flv {param2}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

Dan*_*eck 9

人们xargs与 find 结合使用的原因是多个文件名将传递给任何程序xargs启动的同一个程序调用。例如,如果find返回文件foobarbaz,以下将mv只运行一次:

find sourceDir [...] -print0 | xargs -0 mv -t destDir
Run Code Online (Sandbox Code Playgroud)

实际上,它调用mv如下:

mv -t destDir foo bar baz
Run Code Online (Sandbox Code Playgroud)

如果您不需要或不想要这种行为(我认为这里就是这种情况),您可以简单地使用find's -exec


在这种情况下,一个简单的解决方案是编写一个简短的 shell 脚本,如下所示:

#!/usr/bin/env bash
[[ -f "$1" ]] || { echo "$1 not found" ; exit 1 ; }
P="$1"
F="$( basename $P )"
ffmpeg -i "$P" -f flv "$F"
Run Code Online (Sandbox Code Playgroud)

另存为myffmpeg.sh并运行chmod +x myffmpeg.sh。然后,运行以下命令:

find . -iname "*.mov" -exec /path/to/myffmpeg.sh {} \;
Run Code Online (Sandbox Code Playgroud)

这将为找到的每个文件调用一次 shell 脚本。shell 脚本依次从完整路径中提取文件名,并ffmpeg使用适当的参数进行调用。


Mat*_*erg 4

像这样的东西可以做到这一点并保留完整路径、处理空间、重命名folder/movie.movfolder/movie.flv等。

find . -name "*.mov" | while read movie;do
  ffmpeg -i "$movie" -f flv "${movie%.mov}.flv"
done
Run Code Online (Sandbox Code Playgroud)

如果我误解了您的意思,并且您想要当前目录中的所有 .flv 电影,请改用这个:

find . -name "*.mov" | while read movie;do
  ffmpeg -i "$movie" -f flv "$(basename "${movie%.mov}.flv")"
done
Run Code Online (Sandbox Code Playgroud)

  • 如果您想将其作为一行,只需将所有内容放在一行即可。;) (4认同)