如何在find命令的输出上执行“for each”操作?

5
我想找到所有分辨率为1920x1080的mp4文件。
如果我执行
find . -type f -name \*.mp4 -exec ffprobe '{}' \; 2>&1

它将查找所有的mp4 文件并显示视频信息。例如输出将包含(除其他行外):
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from './5432223.mp4':
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1920x1080, 1744 kb/s, 29.97 fps, 29.97 tbr, 60k tbn, 59.94 tbc

我的当前想法是:
find . -type f -name \*.mp4 -print0|xargs -0 -n1 echo
for f in $(find . -type f -name \*.mp4); do ffprobe $f 2>&1 | grep 1920x1080;done

如何输出仅包含路径的文件名,如果输出匹配了“1920x1080”?
我无法想出如何在第一个命令中加入“if grep -q 1920x1080”,而在第二个命令中,文件名中的空格会混乱输出。
2个回答

3

类似这样:

find -type f -name "*.mp4" -print0 | while read -d $'\0' file
do
    ffprobe "$file" 2>&1 | grep -q 1920x1080 
    # grep will return zero if the pattern was found:
    if [ $? = 0 ] ; then
        echo "$file"
    fi  
done

如果我在for循环中插入echo $file,那么文件名会出现非常奇怪的问题。空格是一个问题,所有的文件名都在同一行上。 - Sandra Schlichting
随着最新的更改,输出结果是一行非常长的所有文件名,但仍然没有正确的输出文件名。 - Sandra Schlichting
@SandraSchlichting,是的,我现在明白了...看起来IFS的工作方式和我期望的不同。我会找到一个解决方案... - hek2mgl
现在它可以工作了 =) 非常感谢。read -d $'\0' 这个技巧非常酷。 - Sandra Schlichting
谢谢!:) 很不幸,我目前不确定为什么我的第一次尝试没有成功。我会调查一下。 - hek2mgl

3
您可能需要执行一个shell命令。类似以下内容:

find . -type f -name \*.mp4 -exec sh -c 'ffprobe "$0" 2>&1 |
    grep -q 1920x1080 && echo "$0"' {} \;

由于某些原因,only 仅适用于没有空格的文件。我从未见过 shfind 中被使用。这会带来什么好处? - Sandra Schlichting
当然,它只适用于没有空格的文件。如果需要那种可恶的用例,请添加双引号!(回答已编辑) - William Pursell
你为什么使用新的 shell? - Sandra Schlichting
新的 shell 必须处理 exec 命令内部的流程控制。(如果有一种不需要 shell 的方法来实现这个功能,我不知道。) - William Pursell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接