如何打印第三个和第四个双引号之间的内容

如何打印第三个和第四个双引号之间的内容

我有一些来自 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

由于第一个字段不再包含嵌入的分隔符,米勒会自动删除引号。

请注意--csvto (与 一起使用--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}'

相关内容