为什么在这种情况下必须在 match 函数之前使用 gsub 函数?
Why does the gsub function have to be used before match function in this instance?
我正在解析一个如下所示的 auth.log 文件:
Dec 4 00:22:36 ip-172-31-23-55 sshd[3033]: Connection from 85.93.5.70 port 50208 on 172.31.23.55 port 22
转换为如下所示的 CSV 输出:
Dec, 4, 00 22 36, 85.93.5.69
下面的 awk 代码正确地产生了我想要的,就像上面的例子一样:
BEGIN {
OFS=", "
}
{
gsub(/:/, " ", )
match([=12=], /([1-9]{1,3}[\.]){3}[0-9]{1,3}/)
print , , , substr([=12=], RSTART, RLENGTH)
}
但是,如果我翻转 gsub 和匹配函数,如
BEGIN {
OFS=", "
}
{
match([=13=], /([1-9]{1,3}[\.]){3}[0-9]{1,3}/)
gsub(/:/, " ", )
print , , , substr([=13=], RSTART, RLENGTH)
}
我得到以下输出:
Dec, 4, 00 22 36, from, 85.
这没什么意义。 gsub 只是在寻找“:”,匹配找到一个 IP 地址。使用 sub 而不是 gsub 时会观察到相同的行为。
我很困惑这些功能是如何互相踩踏的。
当您修改 $3 时,awk 重新编译记录,用您的 2 个字符的 OFS 值替换每个空白字符,因此 $0 的长度不再与之前相同,因此重新编译记录之前的 RSTART 值未指向到新编译记录中的预期字符。看:
$ awk 'BEGIN { OFS=", " } { print; gsub(/:/, " ", ); print }' file
Dec 4 00:22:36 ip-172-31-23-55 sshd[3033]: Connection from 85.93.5.70 port 50208 on 172.31.23.55 port 22
Dec, 4, 00 22 36, ip-172-31-23-55, sshd[3033]:, Connection, from, 85.93.5.70, port, 50208, on, 172.31.23.55, port, 22
^
NOTE |
请注意,当您执行 match() 时 85.93.5.70
开始,现在 from,
开始于相同的字符数(即保存在 RSTART
中的值)。
我强烈推荐 Arnold Robbins 的 Effective Awk Programming,第 4 版。
能否请您尝试关注并告诉我这是否对您有帮助。
echo "Your_Input_as mentioned_above" | awk --re-interval '{split(, A,":");match([=10=],/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/);print , , A[1], A[2], A[3],substr([=10=],RSTART,RLENGTH)}'
希望这对您有所帮助。我也在 GNU awk 中对此进行了测试。
我正在解析一个如下所示的 auth.log 文件:
Dec 4 00:22:36 ip-172-31-23-55 sshd[3033]: Connection from 85.93.5.70 port 50208 on 172.31.23.55 port 22
转换为如下所示的 CSV 输出:
Dec, 4, 00 22 36, 85.93.5.69
下面的 awk 代码正确地产生了我想要的,就像上面的例子一样:
BEGIN {
OFS=", "
}
{
gsub(/:/, " ", )
match([=12=], /([1-9]{1,3}[\.]){3}[0-9]{1,3}/)
print , , , substr([=12=], RSTART, RLENGTH)
}
但是,如果我翻转 gsub 和匹配函数,如
BEGIN {
OFS=", "
}
{
match([=13=], /([1-9]{1,3}[\.]){3}[0-9]{1,3}/)
gsub(/:/, " ", )
print , , , substr([=13=], RSTART, RLENGTH)
}
我得到以下输出:
Dec, 4, 00 22 36, from, 85.
这没什么意义。 gsub 只是在寻找“:”,匹配找到一个 IP 地址。使用 sub 而不是 gsub 时会观察到相同的行为。
我很困惑这些功能是如何互相踩踏的。
当您修改 $3 时,awk 重新编译记录,用您的 2 个字符的 OFS 值替换每个空白字符,因此 $0 的长度不再与之前相同,因此重新编译记录之前的 RSTART 值未指向到新编译记录中的预期字符。看:
$ awk 'BEGIN { OFS=", " } { print; gsub(/:/, " ", ); print }' file
Dec 4 00:22:36 ip-172-31-23-55 sshd[3033]: Connection from 85.93.5.70 port 50208 on 172.31.23.55 port 22
Dec, 4, 00 22 36, ip-172-31-23-55, sshd[3033]:, Connection, from, 85.93.5.70, port, 50208, on, 172.31.23.55, port, 22
^
NOTE |
请注意,当您执行 match() 时 85.93.5.70
开始,现在 from,
开始于相同的字符数(即保存在 RSTART
中的值)。
我强烈推荐 Arnold Robbins 的 Effective Awk Programming,第 4 版。
能否请您尝试关注并告诉我这是否对您有帮助。
echo "Your_Input_as mentioned_above" | awk --re-interval '{split(, A,":");match([=10=],/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/);print , , A[1], A[2], A[3],substr([=10=],RSTART,RLENGTH)}'
希望这对您有所帮助。我也在 GNU awk 中对此进行了测试。