使用记录分隔符后仅打印具有匹配字段的记录
Only print records that have a matching field after using a record separator
我有一堆记录,我只想查看一个字段(或多个字段)与正则表达式模式匹配的记录。
例如,假设我的数据采用如下形式:
Time=181 ms
RequestId=12345
Method=GET
... # other records
EndTime=Tue Mar 5 16:21:03 2015 UTC
EOE
------------------------------------------------------------------------
Time=4003 ms
RequestId=53224
Method=POST
... # other records
EndTime=Tue Mar 5 16:21:09 2015 UTC
EOE
------------------------------------------------------------------------
我之前的做法是使用 grep
和 -A
和 -B
标志来提取上下文。
zgrep "16:2[0-5]:" -A 1 -B 10 data.txt
如果我正在寻找单一模式并且每条记录具有相同数量的行,这很好用,但一旦我必须寻找具有自己模式的多个字段时就会变得更加复杂。
我想要做的是将这些输入中的每一个都分成一条记录,然后只打印与我要查找的模式匹配的 1 个或多个字段的每条记录。
我可以使用 RS
将它们拆分成记录,但我如何只打印具有不同部分匹配的记录?假设我想查找在 16:20
和 16:30
之间具有 EndTime
并且 Time
超过 1 秒 ([0-9]{4,}
) 的所有记录中间有任意数量的行?
awk 'BEGIN { RS = "EOE" } { ??? }' data.txt
听起来您的主要问题是如何访问数据,而不是在获得数据后如何对其进行测试,因此:每当输入中有 name=value 对时,构造一个 name2value 是个好主意数组,然后您可以按名称访问值:
$ cat tst.awk
BEGIN { RS="\nEOE\n-+\n"; FS="\n"; OFS="," }
{
delete n2v
for (i=1;i<=NF;i++) {
name = gensub(/=.*$/,"","",$i)
value = gensub(/[^=]+=/,"","",$i)
n2v[name] = value
}
print n2v["Time"], n2v["RequestId"], n2v["Method"], n2v["EndTime"]
}
$ awk -f tst.awk file
181 ms,12345,GET,Tue Mar 5 16:21:03 2015 UTC
4003 ms,53224,POST,Tue Mar 5 16:21:09 2015 UTC
以上使用了一些 GNU awk 扩展。使用 gawk 时间函数来计算您需要做的任何时间。
我有一堆记录,我只想查看一个字段(或多个字段)与正则表达式模式匹配的记录。
例如,假设我的数据采用如下形式:
Time=181 ms
RequestId=12345
Method=GET
... # other records
EndTime=Tue Mar 5 16:21:03 2015 UTC
EOE
------------------------------------------------------------------------
Time=4003 ms
RequestId=53224
Method=POST
... # other records
EndTime=Tue Mar 5 16:21:09 2015 UTC
EOE
------------------------------------------------------------------------
我之前的做法是使用 grep
和 -A
和 -B
标志来提取上下文。
zgrep "16:2[0-5]:" -A 1 -B 10 data.txt
如果我正在寻找单一模式并且每条记录具有相同数量的行,这很好用,但一旦我必须寻找具有自己模式的多个字段时就会变得更加复杂。
我想要做的是将这些输入中的每一个都分成一条记录,然后只打印与我要查找的模式匹配的 1 个或多个字段的每条记录。
我可以使用 RS
将它们拆分成记录,但我如何只打印具有不同部分匹配的记录?假设我想查找在 16:20
和 16:30
之间具有 EndTime
并且 Time
超过 1 秒 ([0-9]{4,}
) 的所有记录中间有任意数量的行?
awk 'BEGIN { RS = "EOE" } { ??? }' data.txt
听起来您的主要问题是如何访问数据,而不是在获得数据后如何对其进行测试,因此:每当输入中有 name=value 对时,构造一个 name2value 是个好主意数组,然后您可以按名称访问值:
$ cat tst.awk
BEGIN { RS="\nEOE\n-+\n"; FS="\n"; OFS="," }
{
delete n2v
for (i=1;i<=NF;i++) {
name = gensub(/=.*$/,"","",$i)
value = gensub(/[^=]+=/,"","",$i)
n2v[name] = value
}
print n2v["Time"], n2v["RequestId"], n2v["Method"], n2v["EndTime"]
}
$ awk -f tst.awk file
181 ms,12345,GET,Tue Mar 5 16:21:03 2015 UTC
4003 ms,53224,POST,Tue Mar 5 16:21:09 2015 UTC
以上使用了一些 GNU awk 扩展。使用 gawk 时间函数来计算您需要做的任何时间。