我有一些来自Linux机器上的web服务的日志。日志看起来如下:
{"log":"[2023-03-09T06:39:10.669Z] \"GET /server/prod?blank=true HTTP/1.1\" 200 - 0 874 1 1 \"-\" \"-\" \"aaad-bbb-ccc-dd-eeeee\" \"example.com:22213\" \"172.16.2.1:10080\"\n","stream":"stdout","time":"2023-03-09T06:39:11.935831787Z"}
如你所见,有一些双引号。我需要打印第三和第四双引号之间的内容,以及第十一和第十二双引号之间的内容。这意味着我想获得如下内容:
"GET /server/prod?blank=true HTTP/1.1\" "example.com:22213\"
我只关心里面的内容。我不关心"
或\
。
发布于 2023-03-09 08:27:56
根据我的计算,您需要第四和第五个双引号之间的文本,然后是第十二和第十三双引号之间的文本:
sed -E 's/^([^"]*"){4}([^"]*")([^"]*"){8}([^"]*").*$/"\2 "\3/'
(使用sed
支持扩展正则表达式,如GNU、各种BSD或Busybox)或
sed 's/^\([^"]*"\)\{4\}\([^"]*"\)\([^"]*"\)\{8\}\([^"]*"\).*$/"\2 "\3/'
(使用任何sed
)。
发布于 2023-03-09 08:40:25
使用jq
,您可以提取和解码log
键的值:
$ jq -r .log file
[2023-03-09T06:39:10.669Z] "GET /server/prod?blank=true HTTP/1.1" 200 - 0 874 1 1 "-" "-" "aaad-bbb-ccc-dd-eeeee" "example.com:22213" "172.16.2.1:10080"
这实际上是一个使用空格字符作为字段分隔符的无头CSV记录,因此我们可以使用CSV感知工具(如米勒 (mlr
) )从这里解析出第二个和第12个字段:
$ jq -r .log file | mlr --csv -N --fs space cut -f 2,12
"GET /server/prod?blank=true HTTP/1.1" example.com:22213
为了使解析更容易,您可能需要使用TSV输出格式:
$ jq -r .log file | mlr --c2t -N --ifs space cut -f 2,12
GET /server/prod?blank=true HTTP/1.1 example.com:22213
米勒会自动删除引号,因为第一个字段不再包含嵌入式分隔符。
注意,--csv
更改为--c2t
(与--icsv
和--otsv
相同),也从--fs
更改为--ifs
(只设置输入字段分隔符,而不是输出字段分隔符)。在这种情况下,将--fs space
更改为--ifs space --ofs tab
会产生与Miller对待TSV和CSV相同的效果(只是字段分隔符不同)。
发布于 2023-03-09 08:52:43
一个示例awk
脚本可以完成这项工作。这使用"
字符作为字段分隔符,因此第一个字段($1
)是第一个"
等之前的部分。
awk -F\" '{print $5 " " $13}'
如果您也想删除反斜杠,可以在脚本中使用例如gsub()
:
awk -F\" '{gsub(/\\/, ""); print $5 " " $13}'
https://unix.stackexchange.com/questions/739155
复制相似问题