从头部和有效负载的一部分中提取内容

时间:2016-12-09 10:14:05

标签: python regex awk sed scripting

我有 data.log 文件中的以下内容。我想提取ts值和有效载荷的一部分(在有效载荷中的deadbeef之后,第三行,从倒数第二个字节开始。请参考预期输出)。

data.log

print 1: file offset 0x0
ts=0x584819041ff529e0 2016-12-07 14:13:24.124834649 UTC
type: ERF Ethernet
dserror=0 rxerror=0 trunc=0 vlen=0 iface=1 rlen=96 lctr=0 wlen=68
pad=0x00 offset=0x00
dst=aa:bb:cc:dd:ee:ff src=ca:fe:ba:be:ca:fe
etype=0x0800
45 00 00 32 00 00 40 00 40 11 50 ff c0 a8 34 35         E..2..@.@.P...45
c0 a8 34 36 80 01 00 00 00 1e 00 00 08 08 08 08         ..46............
08 08 50 e6 61 c3 85 21 01 00 de ad be ef 85 d7         ..P.a..!........
91 21 6f 9a 32 94 fd 07 01 00 de ad be ef 85 d7         .!o.2...........


print 2: file offset 0x60
ts=0x584819041ff52b00 2016-12-07 14:13:24.124834716 UTC
type: ERF Ethernet
dserror=0 rxerror=0 trunc=0 vlen=0 iface=1 rlen=96 lctr=0 wlen=68
pad=0x00 offset=0x00
dst=aa:bb:cc:dd:ee:ff src=ca:fe:ba:be:ca:fe
etype=0x0800
45 00 00 32 00 00 40 00 40 11 50 ff c0 a8 34 35         E..2..@.@.P...45
c0 a8 34 36 80 01 00 00 00 1e 00 00 08 08 08 08         ..46............
08 08 68 e7 61 c3 85 21 01 00 de ad be ef 86 d7         ..h.a..!........
91 21 c5 34 77 bd fd 07 01 00 de ad be ef 86 d7         .!.4w...........

print 3806: file offset 0x592e0
ts=0x584819042006b840 2016-12-07 14:13:24.125102535 UTC
type: ERF Ethernet
dserror=0 rxerror=0 trunc=0 vlen=0 iface=1 rlen=96 lctr=0 wlen=68
pad=0x00 offset=0x00
dst=aa:bb:cc:dd:ee:ff src=ca:fe:ba:be:ca:fe
etype=0x0800
45 00 00 32 00 00 40 00 40 11 50 ff c0 a8 34 35         E..2..@.@.P...45
c0 a8 34 36 80 01 00 00 00 1e 00 00 08 08 08 08         ..46............
08 08 50 74 73 c3 85 21 01 00 de ad be ef 62 e6         ..Pts..!......b.
91 21 ed 4a 8c df fd 07 01 00 de ad be ef 62 e6         .!.J..........b.

我的预期输出

0x584819041ff529e0,85d79121
0x584819041ff52b00,86d79121
0x584819042006b840,62e69121

到目前为止我尝试了什么

我能够提取ts值。我用了

 awk -v ORS="" '$NF == "UTC"{print sep$1; sep=","} END{print "\n"}' data.log
 >> ts=0x584819041ff529e0,ts=0x584819041ff52b00

但是没有成功提取有效载荷内容。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

这是完成任务的一种方法:

0x584819041ff529e0,85d79121
0x584819041ff52b00,86d79121

输出:

-F '=| '                 : set the field seperator to both '=' and 'space'
/^ts=/{printf $2","}     : if pattern 'ts=' found at line beginning, print the second field
/de ad be ef/{something} : if pattern 'de ad be ef' found, do 'something'

说明:

a

最初变量0将等于de ad be ef。如果第一次找到模式if(!a),则15th会成功,因此会打印16tha字段。现在将1设置为de ad be ef。因此,当if(!a)模式在下一行匹配时,1st检查将失败,从而打印2nda字段。现在,将0重置为{{1}}并继续对文件的其余部分执行相同的过程。

答案 1 :(得分:1)

如果你想要sed:

sed -n -e '/^ts/ {s/^ts=\([^ ]*\) \(.*\)/\1/; H;};' \
       -e '/de ad be ef/ {N; s/\(.*\)de ad be ef \([0-9a-f]\+\) \([0-9a-f]\+\) \(.*\) \([0-9a-f]\+\) \([0-9a-f]\+\) \(.*\)/,\2\3\5\6/; H;};' \
       -e '$ {x; s/\n,/,/g p;}' file

如果您对更多信息感兴趣,请询问。

答案 2 :(得分:1)

使用deadbeef作为开关的awk变种

awk -F '[= ]' '/^ts/{s=$2",";a=15} /de ad be ef/{s=s $a $(a+1);if(a==1)print s;a=1}' data.log

和sed变体

sed -n -e '/^ts=/{h;b^J}' -e "/de ad be ef/,//{H;g;s/ts=\([^ ]*\).*\n*de ad be ef \(..\) \(..\).*\n\(..\) \(..\).*/\1,\2\3\4\4/p;}" data.log

info:“^J”是posix版本中的 CTRL + J (新行carractere)和GNU版本中的“;

答案 3 :(得分:1)

使用GNU awk for gensub():

locale: {format: 'DD-MM-YYYY'}

即使deadbeef分成几行,上述内容也会有效。