Answers:
诸如此类的事情将可以解决问题,并保留完整路径,处理空间,重命名folder/movie.mov
为folder/movie.flv
,等等。
find . -name "*.mov" | while read movie;do
ffmpeg -i "$movie" -f flv "${movie%.mov}.flv"
done
如果我误解了您,并且您希望当前目录中的所有.flv电影都可以使用,请改用以下目录:
find . -name "*.mov" | while read movie;do
ffmpeg -i "$movie" -f flv "$(basename "${movie%.mov}.flv")"
done
人们xargs
与find结合使用的原因是,无论xargs
启动什么程序,多个文件名都将传递给同一程序调用。例如,如果find
返回文件foo,bar和baz,则以下内容将mv
仅运行一次:
find sourceDir [...] -print0 | xargs -0 mv -t destDir
实际上,它的调用mv
类似于以下内容:
mv -t destDir foo bar baz
如果你不需要或不想要这种行为(我认为是这里的情况),你可以简单地使用find
的-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"
另存为myffmpeg.sh
并运行chmod +x myffmpeg.sh
。然后,运行以下命令:
find . -iname "*.mov" -exec /path/to/myffmpeg.sh {} \;
这将为找到的每个文件调用一次shell脚本。Shell脚本反过来从完整路径中提取文件名,并ffmpeg
使用适当的参数进行调用。
我没有得到我期望的解决方案,所以我找到了自己的解决方案。@Daniel的回答很好,但是需要一个shell脚本。一个衬板更快,我更喜欢它:)比编写脚本还简单的解决方案。
我可以使用一个参数,basename
并使用和处理它sh -c
find . -iname "*.mov" -print0 | xargs -0 -i sh -c 'ffmpeg -i {} -f flv `basename {}`'
-i告诉xargs {}
用当前参数替换。
``内的命令输出打印为标准输出(bash功能),因此basename {}
将被评估为裸文件名并打印出来。
-0用于正确处理特殊文件名,但是您需要使用带有-print0选项的参数和find一起传递
您必须像上面的所有答案一样来做,但是xargs的精确使用将是这样的:
echo argument1 argument2 argument3 | xargs -l bash -c 'echo this is first:$0 second:$1 third:$2' | xargs
因此,在您的情况下,它将是:
find . -iname "*.mov" -printf "%p %f\n" | xargs -l bash -c 'echo ffmpeg -i $0 -f flv $1' | xargs
PS:这为正在xargs
一个xargs
命令中为多个参数精确寻找答案的人回答了有关xargs的问题。
为什么不简单地移动ffmpeg的选项以适合find命令的结果格式呢?
find . -iname "*.mov" -printf "%p %f\n" | xargs -r -n2 ffmpeg -f flv -i
请注意,在xargs中添加了-r选项,以防止在未找到.mov文件的情况下运行ffmpeg。
我在xargs中添加了-n2选项,以将xargs进程的项数一次限制为两个。在这种情况下,项目是文件路径和文件名。如果未设置-n选项,则xargs将在一次执行中处理尽可能多的输入项。
xargs
通常在寻找有关多个参数的答案,所以可能想查看stackoverflow.com/questions/3770432/…。