Linux 使用 awk 检查两个日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4163257/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:56:36  来源:igfitidea点击:

using awk to check between two dates

linuxparsingshellawk

提问by amadain

I have a file with multiple data structures in it like so:

我有一个包含多个数据结构的文件,如下所示:

eventTimestamp: 2010-03-23T07:56:19.166
result: Allowed
protocol: SMS
payload: RCOMM_SMS

eventTimestamp: 2010-03-23T07:56:19.167
result: Allowed
protocol: SMS
payload: RCOMM_SMS

eventTimestamp: 2010-03-23T07:56:19.186
result: Allowed
protocol: SMS
payload: SMS-MO-FSM

eventTimestamp: 2010-03-23T07:56:19.197
result: Allowed
protocol: SMS
payload: COPS

eventTimestamp: 2010-03-23T07:56:29.519
result: Blocked
protocol: SMS
payload: COPS
type: URL_IWF
result: Blocked

I want to find all of the events that are payload: SMS-MO-FSM or payload: SMS-MO-FSM-INFO that occurred between the times 2010-03-23 12:56:47 and 2010-03-23 13:56:47. When querying this file so far I have used awk in the following manner:

我想找到在 2010-03-23 12:56:47 和 2010-03-23 13 之间发生的所有作为有效载荷的事件:SMS-MO-FSM 或有效载荷:SMS-MO-FSM-INFO: 56:47。到目前为止,在查询此文件时,我以以下方式使用了 awk:

cat checkThis.txt |
awk 'BEGIN{FS="\n"; RS=""; OFS=";"; ORS="\n"}
     ~/eventTimestamp: 2010-03-23T14\:16\:35/ && ~/SMS-MO-FSM-INFO|SMS-MO-FSM$/ {= ""; print 
python -c "import time; ENGINE_TIME_FORMAT='%Y-%m-%dT%H:%M:%S'; print int(time.mktime(time.strptime('2010-03-23T12:52:52', ENGINE_TIME_FORMAT)))"
}'

Which will give me all of the events that occurred on the second of 14:16:35 in 2010-03-23. I am struggling, however, to think of how I could put the date range into my query. I could use the following to put the dates into epoch time but how can I use the following in my awk to check whether the date is between the times needed:

这将为我提供 2010 年 3 月 23 日 14:16:35 中发生的所有事件。然而,我正在努力思考如何将日期范围放入我的查询中。我可以使用以下内容将日期放入纪元时间,但如何在我的 awk 中使用以下内容来检查日期是否在所需时间之间:

#!/usr/local/bin/python
import time, sys
ENGINE_TIME_FORMAT='%Y-%m-%dT%H:%M:%S'
testTime = sys.argv[1]
try:
    print int(time.mktime(time.strptime(testTime, ENGINE_TIME_FORMAT)))
except:
    print "Time to convert %s" % testTime
    raise

I know this could done in Python but I have written a parser in Python for this and I want this method as an alternative checker so I want to use awk if at all possible.

我知道这可以用 Python 完成,但我为此用 Python 编写了一个解析器,我希望将此方法作为替代检查器,因此我想尽可能使用 awk。

I took this a little further and created a python script for time conversion:

我更进一步,创建了一个用于时间转换的 python 脚本:

cat checkThis.txt| awk 'BEGIN {FS="\n"; RS=""; OFS=";"; ORS="\n"; "./firstDate '2010-03-23T12:56:47'" | getline start_time; close("firstDate"); "./firstDate '2010-03-23T13:56:47'" | getline end_time; close("firstDate");} ("./firstDate " | getline) > start_time {= ""; print 
awk 'BEGIN {
        FS  = "\n"
        RS  = ""
        OFS = ";"
        ORS = "\n"
        t1  = "2010-03-23T07:45:00"
        t2  = "2010-03-23T08:00:00"
        m1  = "eventTimestamp: " t1
        m2  = "eventTimestamp: " t2
        }
 ~ /eventTimestamp:/ &&  ~ /SMS-MO-FSM(-INFO)?$/ {
    if ( >= m1 &&  <= m2) print , , , ;
}' "$@"
}' Traceback (most recent call last): File "./firstDate", line 4, in <module> testTime = sys.argv[1] IndexError: list index out of range

I then tried to use getline to assign the conversion to a variable for comparison:

然后我尝试使用 getline 将转换分配给一个变量进行比较:

eventTimestamp: 2010-03-23T07:56:19.186;result: Allowed;protocol: SMS;payload: SMS-MO-FSM

The getline works in the BEGIN and I checked it in the final print but I seem to have problems in the comparison part of the script.

getline 在 BEGIN 中工作,我在最终打印中检查了它,但我似乎在脚本的比较部分有问题。

采纳答案by Jonathan Leffler

The key observation is that you can compare your timestamps using alphanumeric comparisons and get the correct answer - that is the beauty of ISO 8601notation.

关键观察是您可以使用字母数字比较来比较您的时间戳并获得正确答案 - 这就是ISO 8601表示法的美妙之处。

Thus, adapting your code slightly - and formatting to avoid scroll bars:

因此,稍微调整您的代码 - 并格式化以避免滚动条:

#!/usr/bin/awk -f
BEGIN {
        command="date -f\"%s\" -d \"2010-03-23 12:56:47\""; command | getline startTime; close(command)
        command="date -f\"%s\" -d \"2010-03-23 13:56:47\""; command | getline endTime; close(command)
}

##代码## ~ /^eventTimestamp:/ {
        command="date -f\"%s\" -d " ; command | getline currTime; close(command)

        if (currTime >= startTime && currTime <= endTime) {
                printIt="true"
        }else{
                printIt="false";
        }
}

printIt == "true" { print }             

Obviously, you could put this into a script file - you wouldn't want to type it often. And getting the date range entered accurately and conveniently is one of the hard parts. Note that I've adjusted the time range to match the data.

显然,您可以将其放入脚本文件中 - 您不想经常键入它。准确方便地输入日期范围是困难的部分之一。请注意,我已调整时间范围以匹配数据。

When run on the sample data, it outputs one record:

在样本数据上运行时,它输出一条记录:

##代码##

回答by cryptochaos

A bit of a kludge, but this script assumes you have the unix "date" command. Also hard coded your start and end timestamps in the BEGIN block. Note that your test data listed above does not fall within your sample start/end times.

有点麻烦,但这个脚本假设你有 unix "date" 命令。还在 BEGIN 块中硬编码了您的开始和结束时间戳。请注意,上面列出的测试数据不属于您的示例开始/结束时间。

##代码##