我有一些来自 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"}
正如您所看到的,有一些双引号。我需要打印第三个和第四个双引号之间以及第11个和第12个双引号之间的内容。这意味着我想获取如下内容:
"GET /server/prod?blank=true HTTP/1.1\" "example.com:22213\"
我只关心内容。我不在乎"
或\
。
答案1
使用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
) 从中解析出第 2 个和第 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
to (与 一起使用--c2t
相同)和 from to (仅设置--icsv
--otsv
--fs
--ifs
输入字段分隔符,而不是输出字段分隔符)。在这种情况下,更改--fs space
为--ifs space --ofs tab
会产生相同的效果,因为 Miller 将 TSV 和 CSV 视为相同(只是字段分隔符不同)。
答案2
根据我的计算,您需要第四个和第五个双引号之间的文本,然后是第十二个和第十三个双引号之间的文本:
sed -E 's/^([^"]*"){4}([^"]*")([^"]*"){8}([^"]*").*$/"\2 "\3/'
(使用sed
支持扩展正则表达式,如 GNU、各种 BSD 或 Busybox)或
sed 's/^\([^"]*"\)\{4\}\([^"]*"\)\([^"]*"\)\{8\}\([^"]*"\).*$/"\2 "\3/'
(使用任何sed
)。
答案3
一个示例awk
脚本就可以完成这项工作。这使用"
字符作为字段分隔符,因此第一个字段 ( $1
) 是第一个字段之前的部分,"
等等。
awk -F\" '{print $5 " " $13}'
gsub()
如果您也想删除反斜杠,可以在脚本中使用例如:
awk -F\" '{gsub(/\\/, ""); print $5 " " $13}'