我正在处理一些视频,我想测量每个文件夹包含的视频的总长度并将其与相应的文件夹一起输出。当前结构是这样的。
.
└── Parent folder/
├── Trip 1/
│ ├── Video 1
│ └── Video 2
├── Trip 2/
│ ├── Video 3
│ └── Video 4
└── Trip 3/
├── Video 5
└── Video 6
我想要得到的输出是这样的
Parent folder
Trip 1 3h34m
Trip 2 5h14m
Trip 3 8h12m
到目前为止,我能够获得所有 3 个子文件夹的总数,但我无法正确显示文件夹基础。
mediainfo '--Output=Video;%Duration%\n' *.mp4 | awk '{ sum += $1 } END { secs=sum/1000; h=int(secs/3600);m=int((secs-h*3600)/60);s=int(secs-h*3600-m*60); printf("%02d:%02d:%02d\n",h,m,s) }'
我愿意使用 mediainfo 或 ffprobe 包或您建议的任何内容。
答案1
您的方法是正确的,只需要将其嵌套在每个文件夹中。
find . -type d |while IFS= read dir; do
t=$(mediainfo '--Output=Video;%Duration%\n' "$dir"/*.mp4 | awk '
{ sum += $1 }
END {
secs = int(sum / 1000 + 0.5);
h = int(secs / 3600);
m = int((secs - h * 3600) / 60);
s = int(secs - h * 3600 - m * 60);
printf("%02d:%02d:%02d\n", h, m, s)
}') 2>/dev/null
if [ "$t" != "00:00:00" ]; then
echo "$dir: $t"
fi
done \
|sed -r 's:[^/]*/:--/:g; s:((--/)*)--/:\1-- :; s:--/:| :g; s:([| ]*)-:\1|-:'
为了使其适应您在问题中要求的输出小时和分钟,请将语句更改printf
为printf "%dh%02.0fm", h, m + s/60
(这也四舍五入到最接近的分钟)。
我假设您已经理解mediainfo
和awk
命令,因为您提供了它们,尽管我确实将毫秒转换改为四舍五入。我只是将其包装在一个find
调用中,该调用查看当前路径的所有子目录(更改.
为另一条路径)并逐行循环其输出(while IFS= read dir
将读取每一行,即使其中有空格,也会将其读入$dir
。如果您的目录名称中有换行符,这将不起作用)。
由于目录可能不包含任何 .mp4 文件,我将错误从赋值传输$t
到 /dev/null,然后运行测试以确保时间不是00:00:00
(如果您调整了输出,则将其更改为0h00m
)。然后我打印目录和时间。
最后,sed
使用扩展正则表达式 ( -r
) 将其转换为具有四个替换的树 ( s
):
- 将每个父目录名称转换为两个破折号(暂时保留尾部斜杠)
- 删除最后的斜杠
- 剩下的任何父母都应该得到管道和空间
- 添加临时管道