根据文件名中的时间模式生成文件列表


0

我有一个摄像机记录设备,它将生成一个包含视频的结构化文件夹,如下例所示。

我想生成视频文件列表,但只生成给定时间范围内的视频文件。例如: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

我发现大括号扩展模式可以过滤数字,但如何在所有子文件夹中执行

我希望我的解释不要太困惑了:)

谢谢


PM时间是否也确实在AM文件夹中?
Tripleee '18

这是一个错字,因为我手动编辑了示例以使用例没有大的示例。现在已经解决了,谢谢
最多

Answers:


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)

谢谢大家的建议。


不错的解决方案@Max,当然比我的可读性更好。可以使它更加惯用(或更短),但是当然这完全是可选的。是这样的:find -name "*.mp4" | awk -F- 'substr($3,1,2) >= "08" && substr($3,1,2) <= "17"'因为$PWD是默认的find,并且print $0是在awk的默认动作。
爱德华

0

除非我误解了您的要求,否则您可以按照自己喜欢的任何方式组合通配符,包括在子目录中进行匹配。因此,这应该可以满足您的要求:(不过我自己还没有对其进行测试)

/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

(请注意表达式之间的空格。)


我想从上午08点到视频17PM(如所指出的,存在用于记录的每一天一个AM&PM文件夹)。我测试通配符命令为“ LS - {08,09,10,11,12,13,14,15 ,16,17} ????-. mp4 ',它过滤了我的文件,但对于不匹配的结果,它将显示一个条目,例如' /20180201PM/*-08????-*.mp4 ',因为我需要为了具有filename的完整路径,我使用了命令readlink -f * .mp4,但是通过find递归执行readlink命令,它确实输出了奇怪的结果。
马克斯

我如何在find命令中使用此通配符表达式?与ls一起使用的相同通配符与:find一起使用时不返回任何内容。-name或-iname参数。感谢你
马克斯

抱歉@Max,我现在才看到您的评论。不知道您想使用find。组合的通配符表达式不适用于find。由于您的解决方案更具可读性,因此我赞成您的解决方案,而不是改编我的方案。
爱德华

感谢@Edward的评论和编辑。.一开始我不知道什么是最好和最简单的方法。;)
最大

0

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在这种情况下使其简单消失的选项。)

这些是“全局”模式,而不是正则表达式。Bash具有扩展的globbing功能,它更接近于正则表达式,但仍不完全是正则表达式;但这对于此简单任务不是必需的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.