![根据文件名中的时间模式生成文件列表](https://linux22.com/image/1554611/%E6%A0%B9%E6%8D%AE%E6%96%87%E4%BB%B6%E5%90%8D%E4%B8%AD%E7%9A%84%E6%97%B6%E9%97%B4%E6%A8%A1%E5%BC%8F%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E5%88%97%E8%A1%A8.png)
我有一个相机录制设备,它将生成一个包含视频的结构化文件夹,如下例所示。
我想生成一个视频文件列表,但只包含给定时间范围内的视频文件。例如:8h00 到 17:00 之间(此范围之外的视频由于光线不足质量较差)
文件名结构如下:[DATE Folder]AM|PM/sricam-[date]-[time]-sequence#.mp4
对于以下示例,过滤器将仅列出从 8h08:15 开始的文件
/data/20171229AM/sricam-20171229-070814-1514520494.mp4
/data/20171229AM/sricam-20171229-073814-1514522294.mp4
/data/20171229AM/sricam-20171229-080815-1514524095.mp4
/data/20171229PM/sricam-20171229-180815-1513553225.mp4
我发现括号扩展模式可以过滤数字,但如何在所有子文件夹中执行此操作
我希望我的解释不会太混乱:)
谢谢
答案1
经过一些尝试和错误,我发现 awk 更适合做这样的过滤
我找到了这一行解决方案:
find $PWD -name "*.mp4" | awk -F- '{ if ( substr($3,1,2) <= "17" && substr($3,1,2) >= "08") print $0 }'
但让我解释一下:
find $PWD -name "*.mp4" ## find all videos and print full path
awk -F- ## tels awk that the separator is dash character : -
现在我的输出路径示例将被分成 4 个“列”(3 个破折号),并且每列都通过 $n 访问
这里最有趣的一列是 3 美元,因为它包含时间
$0 = /data/20171229AM/sricam-20171229-070814-1514520494.mp4
$1 = /data/20171229AM/sricam
2美元=20171229
3美元=070814
$4 = 514520494.mp4
我们必须进行一个条件过滤:如果小时介于 08 到 17 之间,则打印该行。
substr($3,1,2) ## take the two first chars from $3 column starting at position 1
substr($3,1,2) <= "17"
注意 17 周围的引号,这意味着“转换为字符串”——如果没有它,if 语句中的两个条件永远不会成立
print $0 ## print the whole line (without the splitting)
感谢大家的建议。
答案2
除非我误解了你的要求,否则你可以以任何你喜欢的方式组合通配符,包括在子目录中匹配。所以这应该可以满足你的要求:(不过我自己还没有测试过)
/data/*/sricam-*-{08,09,10,11,12,13,14,15,16,17}????-*.mp4
不清楚您是否想排除从 17:00 开始的视频。如果您需要包括 17:00:00 但排除此后的任何内容(例如),您甚至可以组合几个通配符表达式:
/data/*/sricam-*-{08,09,10,11,12,13,14,15,16}????-*.mp4 /data/*/sricam-*-170000-*.mp4
(请注意表达式之间的空格。)
答案3
Bash 通配符可以轻松解决这个问题。任何允许您传入多个文件名参数的命令也允许您传入多个通配符。
printf '%s\n' 20171229AM/sricam-20171229-0[89]*.mp4 20171229AM/sricam-20171229-1[01]*.mp4 20171229PM/sricam-20171229-1[2-6]*.mp4
您可以使用与循环驱动程序相同的参数:
for file in 20171229AM/sricam-20171229-0[89]*.mp4 20171229AM/sricam-20171229-1[01].mp4 20171229PM/sricam-20171229-1[2-6]*.mp4; do
: things with "$file"
done
也许值得指出的是,shell(Bash 或您正在使用的任何程序)会在运行任何命令之前将通配符扩展为匹配文件列表。(当没有匹配项时,通配符将逐字传递,但您可以指定选项nullglob
使其在这种情况下消失。)
这些是“glob”模式,而不是正则表达式。Bash 有一个扩展的 globbing 功能,它更接近正则表达式,但仍然不完全是正则表达式;但这对于这个简单的任务来说不是必需的。