![使用 awk 或其他 cli 工具提取日志行中的 json 字段](https://linux22.com/image/211173/%E4%BD%BF%E7%94%A8%20awk%20%E6%88%96%E5%85%B6%E4%BB%96%20cli%20%E5%B7%A5%E5%85%B7%E6%8F%90%E5%8F%96%E6%97%A5%E5%BF%97%E8%A1%8C%E4%B8%AD%E7%9A%84%20json%20%E5%AD%97%E6%AE%B5.png)
这是我们当前使用的系统中的日志格式,现在要更改整个系统的日志格式并不容易。我需要一种方法来提取日志及其字段中的 json 对象。这样我就可以更轻松地查看日志,因为当前消息的大小太大。
这是日志格式
A B C {"field name one":value of field , "msg": "a sample message", "c": c}
这是一个示例日志。请注意,字段 A、B、C 没有空格,但 json 对象的字段和值可能有空格。
service_name/syslog.log:2022-09-24T16:18:01.38754199Z stdout F {"level":"info","ts":1664036281.3874626,"msg":"system sample message","host":"host_name","processor":"test","reqId":"1234"}
通过 cli,我只想打印 msg 中的值。我怎样才能做到这一点?
答案1
jq
是操作JSON的常用工具。 将返回JSON 文档中密钥jq -r .msg
的解码值。msg
您可以cut
通过从字段 4 开始提取字段来获取 JSON 数据 ( cut -d ' ' -f 4-
)
因此将它们结合起来:
cut -d ' ' -f 4- | jq -r .msg
例如
echo '2022-09-24T16:18:01.38754199Z stdout F {"level":"info","ts":1664036281.3874626,"msg":"system sample message","host":"host_name","processor":"test","reqId":"1234"}' | cut -d ' ' -f 4- | jq -r .msg
system sample message
答案2
$ jq -r -R 'sub("[^{]*"; "") | fromjson.msg' file
system sample message
这用于jq
将输入读取为一组“原始”文本行。每行的文本都用sub()
in进行修剪jq
,以删除第一行之前的任何内容{
。然后使用 将该文本的其余部分转换为 JSON 对象,并提取fromjson
该对象的值。msg
答案3
使用乐(以前称为 Perl_6)
...使用 Raku 的JSON::Tiny
模块:
~$ raku -MJSON::Tiny -ne 'my %json = from-json($_.comb( / "\{" ~ "\}" .* / ));
put %json{"msg"};' file.txt
或者:
~$ raku -MJSON::Tiny -ne '$_.comb( / "\{" ~ "\}" .* / ) andthen
my %json = from-json($_);
put %json{"msg"};' file.txt
或者:
~$ raku -MJSON::Tiny -ne 'put %(from-json($_.comb( / "\{" ~ "\}" .* / ))){"msg"}; file.txt
注意:上面的代码$_.comb
可以缩写为.comb
. Raku 中的前导.
点很常见:它意味着调用主题变量后面的例程$_
。
上面,Raku编程语言用于提取JSON内容。使用-ne
逐行非自动打印标志逐行读取输入。输入comb
的文本匹配由大括号括起来的零个或多个(贪婪)字符的模式(“波形符”符号,请参阅下面的链接)。使用该方法解析该文本from-json($_)
,并将结果存储在%
-sigiled 哈希中%json
(前两个答案)。
最后输出结果:msg
钥匙取消引用以返回关联的价值。请注意,您可以使用put %json<msg>
而不是双引号形式,并且可以添加一个or next
来跳过没有所需msg
键的行。
输入示例:
service_name/syslog.log:2022-09-24T16:18:01.38754199Z stdout F {"level":"info","ts":1664036281.3874626,"msg":"system sample message","host":"host_name","processor":"test","reqId":"1234"}
示例输出:
system sample message
注意:有时查看语言的数据内部表示很有启发性,因此整个%json
哈希如下所示(使用.say for %json.sort
最后一个语句):
host => host_name
level => info
msg => system sample message
processor => test
reqId => 1234
ts => 1664036281.3874626
https://docs.raku.org/language/regexes#Tilde_for_nesting_structs
https://raku.land/cpan:MORITZ/JSON::Tiny
https://raku.org