jq使用小结
2017/11/2
说起来,不知不觉也在脚本中频繁用到 jq 这个小工具,还是总结一下,顺带也介绍给不清楚的朋友。 一、本段以翻译官网教程为例来演示如何使用。 来源: https://stedolan.github.io/jq/tutorial/ 教程 1、数据来源 GitHub 有一个 JSON API 我们用来玩玩作为示范 这个 URL 获取最近的 5 个 commits curl -s ‘https://api.github.com/repos/stedolan/jq/commits?per_page=5‘ 返回内容:经过格式化的、看起来很舒服的、标准的 JSON 2、格式化输出 但,假设返回的一串未经过格式化输出的 JSON 文本呢?来吧,使用 jq 来格式化一下: jq ‘.‘ 是最简单的表达式,处理一下 input 的内容,格式化输出所有内容 curl -s ‘https://api.github.com/repos/stedolan/jq/commits?per_page=5‘ | jq ‘.‘ 3、过滤出第一个 commit jq ‘.[0]‘ 从 json array 中提取了第一个并输出 curl -s ‘https://api.github.com/repos/stedolan/jq/commits?per_page=5‘ | jq ‘.[0]‘ 4、实际上,我们不想看到一大堆文本,如果能过滤一下,只输出其中 2 个字段就好啦 jq ‘.[0] | {message: .commit.message, name: .commit.committer.name}‘ curl -s ‘https://api.github.com/repos/stedolan/jq/commits?per_page=5‘ | jq ‘.[0] | {message: .commit.message, name: .commit.committer.name}‘ 操作符 | 在 jq 中的用法和 linux 管道命令类似,处理上一个 filter 输出的内容,并使用 {...} 来过滤出我们想要的字段来组成一个新的对象,最后输出我们想要的内容 显然,在一个级联的 json 文本中,咱们可以通过 .commit.message 来获取想要的字段 5、更进一步,我们要看到 array 中所有的内容,而不只是第一个 .[] 从 array 中依次提取了所有的 element 并传递给下一个 filter 去处理 curl -s ‘https://api.github.com/repos/stedolan/jq/commits?per_page=5‘ | jq ‘.[] | {message: .commit.message, name: .commit.committer.name}‘ 6、上面的操作,我们实际上得到了多个 json values 的输出,怎样合并成一个 array 呢? jq 中的数据表现为 JSON values 的数据流,每一个 js 表达式运行后,输出任意数量的 values 数据流序列化时通过在 JSON values 中使用空格来分隔开,这对 cat 这样的命令是友好的,可以通过处理来合并数据、格式化后得到一个标准的 JSON 输出 如果我们想直接得到一个 array 只需要告诉 js 去帮我们处理一下即可。 curl -s ‘https://api.github.com/repos/stedolan/jq/commits?per_page=5‘ | jq ‘[.[] | {message: .commit.message, name: .commit.committer.name}]‘ 7、最后,试试从别的地方提取点数据过来合并到一起输出 [.parents[].html_url]}] 从 .parents 这个节点提取了所有的 .html_url 的 values curl -s ‘https://api.github.com/repos/stedolan/jq/commits?per_page=5‘ | jq ‘[.[] | {message: .commit.message, name: .commit.committer.name, parents: [.parents[].html_url]}]‘ 二、补充实例 1、解析 docker 的 API 获取RestartPolicy # curl -s --unix-socket /var/run/docker.sock http:/v1.30/services |jq ‘.[].Spec | .Name + " -> RestartPolicy.Condition=" + .TaskTemplate.RestartPolicy.Condition‘ "service1 -> RestartPolicy.Condition=any" "service2 -> RestartPolicy.Condition=none" 不妨和下面这个输出对比一下: # curl -s --unix-socket /var/run/docker.sock http:/v1.30/services |jq ‘.[].Spec | {name: .Name, RestartPolicy: .TaskTemplate.RestartPolicy.Condition}‘ { "name": "service1", "RestartPolicy": "any" } { "name": "service2", "RestartPolicy": "none" } XYWX、参考 1、doc https://stedolan.github.io/jq/tutorial/ 2、Using jq to parse and display multiple fields in a json serially https://stackoverflow.com/questions/28164849/using-jq-to-parse-and-display-multiple-fields-in-a-json-serially
原文地址:http://nosmoking.blog.51cto.com/3263888/1978512