假设我有这些文件:
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工具?
答案 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}}'