我,新手,已搜查这个论坛高与低,并已尝试了几种awks,SEDS,和里grep。
我试图寻找一个日期和时间内日志文件输出所有日志。
不幸的是,我正在寻找所有的日志都有不同的日期格式 。
我没有得到这个工作:
awk '$0 >= "2018-08-23.11:00:00" && $0 <= "2018-08-23.14:00:00"' catalina.out
对于具体的日期格式。
我不能让这些日期格式的工作,也许问题与间距?
2018年8月23日11:00:00,或2018年8月23日11:00:00
什么我曾尝试一些例子:
sed -n '/2018-08-23 16:00/,/2018-08-23 18:00/p' testfile.txt
sed -n '/Feb 23 13:55/,/Feb 23 14:00/p' testfile.txt
awk '$0 >= "2018-08-23 17:00:00" && $0 <= "2018-08-23 19:00:00"' testfile.txt
我也曾尝试设置变量:FROM = “2018年8月23日17:00:00”,TO = “2018年8月23日19:00:00”
awk '$0 >= "$FROM" && $0 <= "$TO"' testfile.txt
谁能帮我这个?
更新 :我得到这个为2018年8月23日11:00:00格式工作
grep -n '2018-08-23 11:[0-9][0-9]' testfile.txt | head -1
grep -n '2018-08-23 12:[0-9][0-9]' testfile.txt | tail -1
awk 'NR>=2 && NR<=4' testfile.txt > rangeoftext
但我无法得到它与2018年8月23日11:00:00工作 - 再次,我觉得这可能是一个空间的问题? 不知道如何解决....
这是一个棘手的问题。 grep
和sed
没有日期的概念,甚至GNU awk
有日期和时间的有限支持。
如果你使用一个健全的日期格式,即可以在字符串比较中使用的日期格式,如这一问题变得有点更容易处理2018-08-15 17:00:00
。 无论字符串是否包含空格或没有这应该工作。 然而,要注意的工具,自动分割上的空白,如外壳和awk
。
现在,你的例子:
sed -n '/2018-08-23 16:00/,/2018-08-23 18:00/p' testfile.txt
sed -n '/Feb 23 13:55/,/Feb 23 14:00/p' testfile.txt
awk '$0 >= "2018-08-23 17:00:00" && $0 <= "2018-08-23 19:00:00"' testfile.txt
前两个应该工作,但前提是该文件确实既包含时间戳,因为你只检查某些任意字符串的存在。 第三还应该工作,前提是这些记录都带有时间戳开始。
这可能是你在找什么(作出有关输入文件可能是什么样子的一些假设):
$ cat file
Aug 22, 2018 11:00:00 bad
2018-08-23 11:00:00 good
Aug 23, 2018 11:00:00 good
2018-08-24 11:00:00 bad
$ cat tst.awk
BEGIN {
min = raw2dt(min)
max = raw2dt(max)
}
{ cur = raw2dt($0) }
(cur >= min) && (cur <= max)
function raw2dt(raw, tmp, mthNr, dt, fmt) {
fmt = "%04d%02d%02d%02d%02d%02d"
if ( match(raw,/[0-9]{4}(-[0-9]{2}){2}( [0-9:]+)?/) ) {
split(substr(raw,RSTART,RLENGTH),tmp,/[^[:alnum:]]+/)
dt = sprintf(fmt, tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6])
}
else if ( match(raw,/[[:alpha:]]{3} [0-9]{2}, [0-9]{4}( [0-9:]+)?/) ) {
split(substr(raw,RSTART,RLENGTH),tmp,/[^[:alnum:]]+/)
mthNr = (index("JanFebMarAprMayJunJulAugSepOctNovDec",tmp[1])+2)/3
dt = sprintf(fmt, tmp[3], mthNr, tmp[2], tmp[4], tmp[5], tmp[6])
}
return dt
}
$ awk -v min='Aug 23, 2018 11:00' -v max='2018-08-23 11:00' -f tst.awk file
2018-08-23 11:00:00 good
Aug 23, 2018 11:00:00 good
上述工作将在任何UNIX系统中的任何外壳使用任何POSIX awk的。
当试图获得一组中出现两个日期之间的日志条目,一个不应该使用sed
检查此。 是的,这是事实,SED具有凉爽,非常有用的功能,以检查地址范围(所以没有BTW awk的。),但
sed -n `/date1/,/date2/p` file
并不总是可行的。 这意味着,如果只会工作date1
和date2
实际上是在文件中。 如果他们中的一个缺失,这将失败。
与两个地址编辑命令将选择从通过所述第二匹配的下一个图案空间匹配的第一个地址中的第一图案空间中的包含的范围。
[address[,address]]
最重要的是,比较日期的时候,一个人永远不能,除非你使用一个健全的格式使用字符串比较。 一些理智的格式是YYYY-MM-DD
, YYYY-MM-DD hh:mm:ss
,...一些不好的格式是“2018年8月1日”,因为它涉及“2018年1月1日”之前和“99-01-31”说到后“31年1月1日”或“2018年2月1日”,“2018年11月1日”后,来
所以,如果可以的话,尝试转换你的约会,你获得到一个理智的格式。 所述sanest格式计算的时间差WRT的时代。 Unix有允许自1970-01-01 00:00:00 UTC的UNIX EPOCH计算的秒数各种工具。 这是你的真实意图。
至于你提到,你的日志文件有多种日期格式,而这并没有使事情变得简单。 尽管GNU AWK具有各种时间函数 ,它们需要你知道的格式事前。
因为我们不知道哪些格式的日志文件中都存在,我们将使用Unix函数的date
具有一个知道的格式很多非常复杂的解释。
另外,我会作一个假设,在awk
你能够唯一标识日期莫名其妙地存储在一个名为字符串日期date
。 也许有,让你做这个日期之后总是出现特殊字符:
例如输入的文件:
2018-08-23 16:00 | some entry
Aug 23 2018 16:01:01 | some other entry
所以,在这种情况下,我们可以说:
awk -F| -v t1=$(date -d "START_DATE" "+%s") \
-v t2=$(date -d "END_DATE" "+%s") \
'{date=$1}
{cmd="date -d \""$1"\" +%s"; cmd | getline epoch; close cmd}
(t1 <= epoch && epoch <= t2)' testfile