考虑将 GNU awk 用于 FPAT:
$ cat tst.awk
BEGIN {
FPAT="([^[:space:]=]+=)?(\"[^\"]+\"|[^[:space:]]+)"
}
{
for (i=1; i<=NF; i++) {
print i, "<" $i ">"
}
}
$ awk -f tst.awk file
1 <"09/Feb/2019:11:25:51 +0000">
2 <client=10.0.0.148>
3 <method=GET>
4 <request="GET /flask2 HTTP/1.1">
5 <[...]>
6 <request_time=0.011>
7 <[...]>
8 <upstream_header_time=0.011>
鉴于上述解析输入的方法,您可以轻松识别要输出的字段,甚至可以简单地通过名称或位置引用它们,例如:
$ cat tst.awk
BEGIN {
FPAT="([^[:space:]=]+=)?(\"[^\"]+\"|[^[:space:]]+)"
}
{
f["time"] = $1
for (i=2; i<=NF; i++) {
tag = val = $i
sub(/=.*/,"",tag)
sub(/^[^=]+=/,"",val)
f[tag] = val
}
print f["time"], f["request"], f["request_time"]
}
$ awk -f tst.awk file
"09/Feb/2019:11:25:51 +0000" "GET /flask2 HTTP/1.1" 0.011
考虑一下,如果您想在 CSV 中以特定的字段顺序额外打印客户端 IP 地址和方法,并且所有字段都被双引号括起来,或者做任何其他事情,例如:
$ cat tst.awk
BEGIN {
FPAT="([^[:space:]=]+=)?(\"[^\"]+\"|[^[:space:]]+)"
OFS=","
}
{
f["time"] = $1
for (i=2; i<=NF; i++) {
tag = val = $i
sub(/=.*/,"",tag)
sub(/^[^=]+=/,"",val)
gsub(/^"|"$/,"",val)
f[tag] = "\"" val "\""
}
print f["time"], f["request"], f["request_time"], f["client"], f["method"]
}
$ awk -f tst.awk file
"09/Feb/2019:11:25:51 +0000","GET /flask2 HTTP/1.1","0.011","10.0.0.148","GET"