我有一些来自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
复制相似问题