我有一个包含多个数据结构的文件,如下所示:
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
我想找到所有有效载荷的事件:SMS-MO-FSM或有效载荷:在2010-03-23 12:56:47和2010-03-之间发生的SMS-MO-FSM-INFO- 23 13:56:47到目前为止查询此文件时,我已按以下方式使用awk:
cat checkThis.txt |
awk 'BEGIN{FS="\n"; RS=""; OFS=";"; ORS="\n"}
$1~/eventTimestamp: 2010-03-23T14\:16\:35/ && $4~/SMS-MO-FSM-INFO|SMS-MO-FSM$/ {$1=$1 ""; print $0}'
这将为我提供2010-03-23 14:16:35第二次发生的所有事件。但是,我正在努力思考如何将日期范围放入我的查询中。我可以使用以下内容将日期放入纪元时间但是如何在我的awk中使用以下内容来检查日期是否在所需时间之间:
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)))"
我知道这可以在Python中完成,但我已经在Python中编写了一个解析器,我希望这个方法作为替代检查器,所以我想尽可能使用awk。
我更进一步,并为时间转换创建了一个python脚本:
#!/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
然后我尝试使用getline将转换分配给变量进行比较:
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 $1" | getline) > start_time {$1=$1 ""; print $0}'
Traceback (most recent call last):
File "./firstDate", line 4, in <module>
testTime = sys.argv[1]
IndexError: list index out of range
getline在BEGIN中工作,我在最终打印中检查了它,但我似乎在脚本的比较部分有问题。
答案 0 :(得分:6)
关键的观察是,您可以使用字母数字比较来比较您的时间戳,并获得正确的答案 - 这是ISO 8601符号的美妙。
因此,稍微调整代码 - 并格式化以避免滚动条:
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
}
$1 ~ /eventTimestamp:/ && $4 ~ /SMS-MO-FSM(-INFO)?$/ {
if ($1 >= m1 && $1 <= m2) print $1, $2, $3, $4;
}' "$@"
显然,您可以将其放入脚本文件中 - 您不希望经常输入它。准确方便地输入日期范围是其中一个难点。请注意,我已调整时间范围以匹配数据。
在样本数据上运行时,它会输出一条记录:
eventTimestamp: 2010-03-23T07:56:19.186;result: Allowed;protocol: SMS;payload: SMS-MO-FSM
答案 1 :(得分:1)
有点像kludge,但是这个脚本假设你有unix“date”命令。还对BEGIN块中的开始和结束时间戳进行了硬编码。请注意,上面列出的测试数据不在您的样本开始/结束时间范围内。
#!/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)
}
$0 ~ /^eventTimestamp:/ {
command="date -f\"%s\" -d " $2; command | getline currTime; close(command)
if (currTime >= startTime && currTime <= endTime) {
printIt="true"
}else{
printIt="false";
}
}
printIt == "true" { print }