有一些日志文件。
$> cat ./text
Tue, 28 Feb 2012 15:43:20 407a3f8bbf704e41bef1f4c0ac24f310 FAILED
Tue, 2012 15:45:10 525b13aed6094417a56fd7bc67a10ad7 FAILED
Tue, 28 Feb 2012 15:47:08 ae3e2dc3e5b14d0eb7338ab308a32c8e
Tue, Feb 2012 15:52:26 18486cbede4e4cb4bee931bf29823dda FAILED
Tue, 28 Feb 2012 15:54:17 3c96983a68dd4c5e968dcad512bf77e9 FAILED
Tue, Feb 2012 15:56:30 2191e5260aa44a2a8997c47d710d6fbb FAILED
Tue, 28 Feb 2012 15:58:25 083fc56361414695b4e5cf54f8c57a9e FAILED
28 Feb 2012 16:01:55 5cbad64d2d62429c97ed7fdf98087c44 FAILED
Tue, 28 Feb 2012 16:03:37 a0d33b998b8247ffbecb984198453c0b
28 Feb 2012 16:05:32 cf9c1893e8b64aa89636a8cfeff56cf2 FAILED
Tue, 28 Feb 2012 16:06:53 027d99f7fa68436d9000661a7af07e2a PASSED
使用grep
很容易获得所有十六进制值。
$> grep --only-matching --perl-regex "[0-9a-f]{32}" ./text
407a3f8bbf704e41bef1f4c0ac24f310
525b13aed6094417a56fd7bc67a10ad7
ae3e2dc3e5b14d0eb7338ab308a32c8e
18486cbede4e4cb4bee931bf29823dda
3c96983a68dd4c5e968dcad512bf77e9
2191e5260aa44a2a8997c47d710d6fbb
083fc56361414695b4e5cf54f8c57a9e
5cbad64d2d62429c97ed7fdf98087c44
a0d33b998b8247ffbecb984198453c0b
cf9c1893e8b64aa89636a8cfeff56cf2
027d99f7fa68436d9000661a7af07e2a
但是如何使用awk
来完成?
所以实际的问题是:我如何减去一些值,匹配一些正则表达式,来回给定一个字符串?例如,在awk
的某些行 - 源文件中,我有$ 0值,实际上是整个字符串,如"Tue, Feb 2012 15:56:30 2191e5260aa44a2a8997c47d710d6fbb FAILED"
。我正在寻找一些awk
命令来获取十六进制值,如:
hex = command_name( $0, "[0-9a-f]{32}" )
hex
将等于2191e5260aa44a2a8997c47d710d6fbb
。
我该怎么做?
答案 0 :(得分:1)
你可以使用match()(--re-interval可能需要gawk):
$ gawk --re-interval '{ match($0, /[0-9a-fA-F]{32}/,arr); print arr[0]; }' testdata
407a3f8bbf704e41bef1f4c0ac24f310
525b13aed6094417a56fd7bc67a10ad7
ae3e2dc3e5b14d0eb7338ab308a32c8e
18486cbede4e4cb4bee931bf29823dda
3c96983a68dd4c5e968dcad512bf77e9
2191e5260aa44a2a8997c47d710d6fbb
083fc56361414695b4e5cf54f8c57a9e
5cbad64d2d62429c97ed7fdf98087c44
a0d33b998b8247ffbecb984198453c0b
cf9c1893e8b64aa89636a8cfeff56cf2
027d99f7fa68436d9000661a7af07e2a
答案 1 :(得分:0)
原始awk
程序不支持regex-replace中的反向引用。如果你很幸运并且可以访问GNU awk,你可以使用sub()
函数来提取字符串的一部分。理论上它的工作原理如下:
hex = sub(/^.* ([0-9a-fA-F]+) .*$/, "\1");
由于我手边没有GNU awk,你必须四处寻找正确的语法(例如"\1"
与"\\1"
,+
vs {32,32}
,等等。)
答案 2 :(得分:0)
也许你可以尝试GNU扩展gensub()
$ awk --re-interval '{print gensub(/^.*([0-9a-f]{32}).*$/,"\\1","")}' text
407a3f8bbf704e41bef1f4c0ac24f310
525b13aed6094417a56fd7bc67a10ad7
ae3e2dc3e5b14d0eb7338ab308a32c8e
18486cbede4e4cb4bee931bf29823dda
3c96983a68dd4c5e968dcad512bf77e9
2191e5260aa44a2a8997c47d710d6fbb
083fc56361414695b4e5cf54f8c57a9e
5cbad64d2d62429c97ed7fdf98087c44
a0d33b998b8247ffbecb984198453c0b
cf9c1893e8b64aa89636a8cfeff56cf2
027d99f7fa68436d9000661a7af07e2a
答案 3 :(得分:0)
非GNU awk回答
awk '
{
for (i=NF; i>0; i--)
if (length($i)==32 && ! match($i,/[^0-9a-fA-F]/)) {
hexvalue = $i
break # if you only expect one per line
}
print hexvalue # or do something else
}
'
答案 4 :(得分:0)
这可能有用或者你:
awk --re-interval -vRS='[0-9a-fA-F]{32}' 'RT{print RT}' file
答案 5 :(得分:0)
如果您的日志文件的结构与显示的样本一致:
awk '{print $6}' ./text