shell里的json超级工具 jq 高级用法介绍

Linux shell 环境下有个和google Gson 一样好用的JSON 数据处理工具jq.
最近发现用jq 来分析提取数据,简直太好用了,特别是用于处理shell环境下面的复杂数据结构时,显的很方便。

实际问题1: 如何获取mesos 网页上的mesos-agent host 名称。

如下图:
在这里插入图片描述
查询了mesos api, 发现可以/master/slaves 获取所有数据。
curl -s http://10.2.1.72:5050/master/slaves | jq | less
在这里插入图片描述
curl -s http://10.2.1.72:5050/master/slaves | jq ‘.slaves’ | jq [.[].hostname]

happy:tmp happy$ curl -s http://10.2.1.72:5050/master/slaves | jq ‘.slaves’ | jq [.[].hostname]
[
mesos-agent1.cityworks.cn”,
mesos-agent2.cityworks.cn”,
mesos-agent3.cityworks.cn
]

如果不用jq 这个专业的JSON处理工具,用传统的grep ,tr 命令也可以实现,但是效果差很多,稳定性差, 在复杂的条件下,不能确保每次结果都是正确的。
特别是目标没有明显的规律时,就很难操作.

下面是jq在不同平台的安装和用法举例

安装
在OS X上安装jq:

brew install jq

或者在Ubuntu上:

apt-get install jq

Centos上:yum install -y jq

Alpine Linux: apk add jq

下面内容来自国外网页翻译:
用法
jq是围绕过滤器构建的。 最简单的过滤器是。,它回应了它的输入,但很漂亮:
$ echo ‘{“hello”:{ “greetings”:“to you”}}’ | jq .
{
“hello”: {
“greetings”: “to you”
}
}

例如,当您点击JSON API时,它非常适合从curl打印输出。
正如编写良好的手册所指出的,最简单有用的过滤器是.field,它从每个记录中提取字段:
$ echo ‘{“hello”:{ “greetings”:“to you”}}’ | jq .hello
{
“greetings”: “to you”
}
我们也可以为嵌套哈希做.field1.field2:

$ echo ‘{“hello”:{ “greetings”:“to you”}}’ | jq .hello.greetings
“to you”

让我们在一些真正的输入上使用jq。 这是一个名为1.json的Slack日志:

[
{
“type”: “message”,
“user”: “U024HFHU5”,
“text”: “hey there”,
“ts”: “1385407681.000003”
},
{
“type”: “message”,
“user”: “U024HGJ4E”,
“text”: “right back at you”,
“ts”: “1385407706.000006”
}
]

要从1.json中拉出每个Slack消息中的文本,我们需要首先使用。.[]进入“数组”。 然后我们可以使用|将数组中的每个对象传递给下一个过滤器,并使用.text从每个对象中获取文本字段:

$ jq “.[] | .text” 1.json
“hey there”
“right back at you”
Note that we now have plain-text representations of each value, so we could go back to sed:

$ jq “.[] | .text” 1.json | sed ‘s/h/H/g’
“Hey tHere”
“rigHt back at you”

转换输入
到目前为止,我们一直在拔出字段并显示它们。 现在让我们在显示它之前转换JSON。 让我们展示用户和文字:
$ jq “.[] | { the_user: .user, the_text: .text }” 1.json
{
“the_user”: “U024HFHU5”,
“the_text”: “hey there”
}
{
“the_user”: “U024HGJ4E”,
“the_text”: “right back at you”
}
.[]进入数组,给我们一个对象数组。 然后我们使用|将这些对象传递给下一个过滤器,并使用{}过滤器使用每个对象的字段构造一个新对象。 我们还将用户重命名为the_user,将文本重命名为the_text。

要在数组中包装内容,请在表达式周围加上括号:

$ jq “[.[] | { the_user: .user, the_text: .text }]” 1.json
[
{
“the_user”: “U024HFHU5”,
“the_text”: “hey there”
},
{
“the_user”: “U024HGJ4E”,
“the_text”: “right back at you”
}
]
请注意,我们将整个表达式包装在[]中,而不仅仅是{}部分。 如果我们将{}部分包装在方括号中,那么会将每个对象放在一个单独的数组中,这通常是我们不想要的:

$ jq “.[] | [{ the_user: .user, the_text: .text }]” 1.json
[
{
“the_user”: “U024HFHU5”,
“the_text”: “hey there”
}
]
[
{
“the_user”: “U024HGJ4E”,
“the_text”: “right back at you”
}
]

处理多个文件
假设我们有另一个JSON文件,2.json:

[
{
“type”: “message”,
“user”: “U028H5EBL”,
“text”: “<@U02A8N1DS>: Can I get some help with a domain registration?”,
“ts”: “1418301403.001783”
},
{
“type”: “message”,
“user”: “U02A8N1DS”,
“text”: “Sure thing.”,
“ts”: “1418301427.001784”
}
]
我们希望打印出来自1.json和2.json的所有消息,包装在一个数组中,就像我们之前一样。 让我们对两个文件运行相同的过滤器:

$ jq “.[] | [{ the_user: .user, the_text: .text }]” 1.json 2.json
[
{
“the_user”: “U024HFHU5”,
“the_text”: “hey there”
}
]
[
{
“the_user”: “U024HGJ4E”,
“the_text”: “right back at you”
}
]
[
{
“the_user”: “U028H5EBL”,
“the_text”: “<@U02A8N1DS>: Can I get some help with a domain registration?”
}
]
[
{
“the_user”: “U02A8N1DS”,
“the_text”: “Sure thing.”
}
]
嘿,这不好:每个文件的输出都包含在自己的数组中! 我们希望整个输出周围有一个数组,而不是每个文件一个数组。 幸运的是,jq有一个选项:jq --slurp将在1.json和2.json中汇总消息数组并将它们作为一个巨大数组处理。

让我们看看–slurp在我们对其输出做任何事情之前会产生什么:

$ jq --slurp . 1.json 2.json
[
[
{
“type”: “message”,
“user”: “U024HFHU5”,
“text”: “hey there”,
“ts”: “1385407681.000003”
},
{
“type”: “message”,
“user”: “U024HGJ4E”,
“text”: “right back at you”,
“ts”: “1385407706.000006”
}
],
[
{
“type”: “message”,
“user”: “U028H5EBL”,
“text”: “<@U02A8N1DS>: Can I get some help with a domain registration?”,
“ts”: “1418301403.001783”
},
{
“type”: “message”,
“user”: “U02A8N1DS”,
“text”: “Sure thing.”,
“ts”: “1418301427.001784”
}
]
]

正如我们所看到的,它将所有输入包装在一个大数组中,因此我们将在过滤时添加额外的.[]以获取内部对象:
$ jq --slurp “[.[] | .[] | { text: .text }]” 1.json 2.json
[
{
“text”: “hey there”
},
{
“text”: “right back at you”
},
{
“text”: “<@U02A8N1DS>: Can I get some help with a domain registration?”
},
{
“text”: “Sure thing.”
}
]

参考资源链接:[使用jqShell命令行高效处理JSON数据](https://wenku.youkuaiyun.com/doc/64531d49ea0840391e76e489?utm_source=wenku_answer2doc_content) 在Shell命令行中使用jq工具进行高级查询和转换,你可以利用jq提供的丰富功能来提取、修改和操作JSON数据。例如,要实现高级查询,你可以使用jq的过滤器、map函数和select函数来根据特定条件筛选数据。而要进行转换操作,你可以利用jq的高级操作符如+、-、*、/来执行数学运算,或者使用内置函数如length、keys、values来处理JSON结构。 举个例子,假设我们有一个包含多个对象的JSON数组,并且我们想要筛选出其中某个字段符合特定值的对象。使用jq的select函数可以轻松完成这个任务,如:`% jq 'map(select(.age > 30))' people.json`。这条命令会返回people.json中所有年龄大于30的人的信息。 如果需要进行转换操作,比如计算数组中所有数字的平均值,可以使用jq的内置函数,如下所示:`% jq 'map(.age) | add / length' people.json`。这条命令将提取每个人的年龄,计算总和,然后除以人数,得到平均年龄。 此外,jq还支持使用变量和自定义函数进行复杂的数据处理。例如,你可以定义一个函数来格式化日期,然后在查询中使用它。 通过使用jqShell命令行对JSON数据进行高级查询和转换,你可以极大地提升工作效率和数据处理的灵活性。更多高级操作和示例,可以参考《使用jqShell命令行高效处理JSON数据》这本书,它详细介绍jq的各种用法和技巧,对于提高处理JSON数据的能力大有帮助。 参考资源链接:[使用jqShell命令行高效处理JSON数据](https://wenku.youkuaiyun.com/doc/64531d49ea0840391e76e489?utm_source=wenku_answer2doc_content)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开心自由天使

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值