首页 > 解决方案 > BASH:通过另一个命令的返回值过滤文件列表

问题描述

我有一系列目录,其中包含(大部分)视频文件,比如说

test1
  1.mpg
  2.avi
  3.mpeg
  junk.sh
test2
  123.avi
  432.avi
  432.srt
test3
  asdf.mpg
  qwerty.mpeg

video_dir我使用目录名称(基于其他参数)创建一个变量 ( ),并使用它find来生成基本列表。然后,我根据文件类型的另一个变量 ( video_type) 进行过滤(因为有时在目录中存在非视频文件)通过egrep. 然后我随机排列列表并将其保存到文件中。该文件稍后用于mplayer在列表中进行幻灯片放映。我目前使用以下命令来完成此操作。我确信这是一种可怕的方法,但它对我有用,即使在大目录上也很快。

video_dir="/test1 /test2"
video_types=".mpg$|.avi$|.mpeg$"

find ${video_dir} -type f    |
  egrep -i "${video_types}"  |
  shuf > "$TEMP_OUT"

我现在想添加根据视频文件的分辨率高度过滤掉文件的功能。我可以从中得到。

mediainfo --Output='Video;%Height%' filename

它只返回一个数字。我尝试使用 find 的 -exec 功能在每个文件上运行该命令。

 find ${video_dir} -type f -exec mediainfo --Output='Video;%Height%' {} \;

但这只是返回高度列表,而不是文件名,我不知道如何根据比较来拒绝高度,比如 <480。我可以做一个 for next 循环,但这似乎是一个坏(慢)的主意。

使用来自@mark-setchell 的信息,我将其修改为,

video_dir="test1"

find ${video_dir} -type f   \
   -exec bash -c 'h=$(mediainfo --Output="Video;%Height%" "$1"); [[ $h -gt 480 ]]' _ {} \; -print

哪个有效。

标签: linuxbashfindcommandpipe

解决方案


您可以将您的替换egrep为以下内容,以便您仍在find命令中(-iname不区分大小写并-o表示逻辑 OR):

find test1 test2 -type f                                       \
     \( -iname "*.mpg" -o -iname "*.avi" -o -iname "*.mpeg" \) \
     NEXT_BIT

然后,NEXT_BIT 可以-exec bash并以状态 0 或 1 退出,具体取决于您想要包含还是排除当前文件。所以它看起来像这样:

-exec bash -c 'H=$(mediainfo -output ... "$1"); [ $H -lt 480 ] && exit 1; exit 0' _ {} \;

所以,注意到@tripleee 在关于多余exit陈述的评论中的建议,我明白了:

find test1 test2 -type f                                       \
    \( -iname "*.mpg" -o -iname "*.avi" -o -iname "*.mpeg" \)  \
    -exec bash -c 'h=$(mediainfo ...options... "$1"); [ $h -lt 480 ]' _ {} \; -print

推荐阅读