过滤文件名中包含嵌入时间戳的文件

时间:2018-01-24 17:55:09

标签: linux bash grep

假设我有这些文件:

file-foo-1514764800.log
file-foo-1514851200.log
file-foo-1514937600.log
file-foo-1515024000.log
file-foo-1515110400.log

file-bar-1514764800.log
file-bar-1514851200.log
file-bar-1514937600.log
file-bar-1515024000.log
file-bar-1515110400.log 

文件名中的时间戳对应于1月1日到1月5日。如果我想过滤时间戳在Jan 2nd范围内Jan 4th范围内的文件,我需要编写一个表达式,例如>= 1514851200 && <= 1515024000(&gt; = Jan 2nd&amp;&amp; ;&lt; = Jan 4th),并使用它来过滤文件名中的第三项,如果我们使用-作为分隔符。

请注意,在我的情况下,我不能依赖文件的修改日期,因为它们可能在任意时间被修改。在这种情况下,解决方案相当简单:

find . -maxdepth 1 -newermt "2018-01-04" ! -newermt "2017-01-06"

使用bash解决这个问题的简单方法是什么(zsh也很好),以及常见的linux工具?

4 个答案:

答案 0 :(得分:1)

提取日期部分,转换为常规日期,使用该日期触摸文件。然后使用常规查找命令

for f in *.log; do
    fdate=$(basename $f .log | cut -d '-' -f3)
    touch -d "$(date -d @$fdate)" $f
done
# as you wrote
find . -maxdepth 1 -newermt "2018-01-04" ! -newermt "2017-01-06"

答案 1 :(得分:1)

这有点像黑客,但我认为你可以用Awk做到这一点。

awk '{ split(FILENAME, a, "-");
    if (a[3] >= 1514851200 && a[3] <= 1515024000) print FILENAME;
    nextfile }' /path/to/*

这显然是硬编码文件名中破折号的假设。也许您可以使用其他模式轻松提取日期戳,如果这有问题(substr从文件名末尾计算索引?)

答案 2 :(得分:1)

我有一个想法,不完美但很容易。转到日志文件目录并运行以下命令:

for f in *.log; do m=${f/*-*-}; n=${m/.log}; [[ "$n" -ge 1514851200 && "$n" -le 1515024000 ]] && echo "$f"; done 

有关bash参数扩展的更多详细信息:prepared statements

我在bash 4.4.12和zsh 5.4.2中检查了这个命令行。

答案 3 :(得分:0)

这是一个不使用shell脚本的版本,它不会改变文件的修改时间(假设文件名中没有管道&#39; |&#39;字符):

find . -maxdepth 1 -regextype egrep -regex '^.*-[0-9]{1,10}\.log$'
  | sed -r 's/^(.*-([0-9]{1,10}))\.log$/&|\2/'
  | awk -F '|' '("/bin/date -Is -d@"$2 | getline line)
    {if(line >= "2017-01-06" && line <= "2018-01-04"){print $1}else{next}}'