JSON 是一种轻量级的数据交换格式。其采用完全独立于语言的文本格式,具有方便人阅读和编写,同时也易于机器的解析和生成。这些特性决定了 JSON 格式越来越广泛的应用于现代的各种系统中。作为系统管理员,在日常的工作中无论是编辑配置文件或者通过 http 请求查询信息,我们都不可避免的要处理 JSON 格式的数据。
jq 是一款命令行下处理 JSON 数据的工具。其可以接受标准输入,命令管道或者文件中的 JSON 数据,经过一系列的过滤器(filters)和表达式的转后形成我们需要的数据结构并将结果输出到标准输出中。jq 的这种特性使我们可以很容易地在 Shell 脚本中调用它。
jq 安装jq 是开源软件。目前大部分的 Linux 系统和 Unix 系统的官方软件仓库中均有收录。用户可以通过系统自带的软件包管理器直接安装,也可以手动从源代码编译安装。jq 的源代码可以从其代码仓库中获得。编译 jq 的指令如下:
清单 1. 编译 jq
1 2 3 4 5 6
git clone https://github.com/stedolan/jq.git cd jq autoreconf -i ./configure --disable-maintainer-mode make sudo make install
windows 用户可以通过 Chocolatey NuGet 安装或者直接从官网下载可执行文件。
开始使用 jq 如何调用 jq作为一个标准的命令行工具,jq 支持"-h"选项(或者长格式"--help")。通过该选项,我们可以看到 jq 的简略的使用帮助。在 linux 系统中,我们可以通过 man 命令来查看 jq 详细文档。
jq 可以处理 JSON 文件,也可以直接处理从命令行管道或者流中传入的数据。这方便我们在 shell 脚本中使用。如下面代码:
图 1.jq 命令行帮助 清单 2. jq 直接处理文件
1 2 3 4
#xxx.JSON 中是我们要处理的 JSON 数据,我们可以直接将文件名传给 jq $ jq -r '.' xxx.JSON #或者由其他程序读出文件内容,并传给 jq $ cat xxx.JSON|jq -r '.'
需要说明的是 jq 只能接受 well form 的 JSON 字符串作为输入内容。也就是说输入内容必须严格遵循 JSON 格式的标准。所有的属性名必须是以双引号包括的字符串。对象的最后一个属性的末尾或者数组的最后一个元素的末尾不能有逗号。否则 jq 会抛出无法解析 JSON 的错误。
jq 通过命令行选项来控制对输入输出的处理。选项的具体内容请参见图一中的 jq 帮助。这里介绍几个比较常用和重要的选项。
'-r'选项。该选项控制 jq 是输出 raw 格式内容或 JSON 格式内容。所谓的 JSON 格式是指符合 JSON 标准的格式。例如,假设我们要查询 JSON 字符串{"name":"tom"}中 name 的值. 使用-r 选项时返回的是'tom'. 不使用-r 选项时,返回的是'"tom"'.返回值多了一对双引号。
-s 选项。 jq 可以同时处理空格分割的多个 JSON 字符串输入。默认情况下,jq 会将 filter 分别对每个 JSON 输入应用,并返回结果。使用-s 选项,jq 会将所有的 JSON 输入放入一个数组中并在这个数组上使用 filter。"-s"选项不但影响到 filter 的写法。如果在 filter 中需要对数据进行选择和映射,其还会影响最终结果。
--arg 选项。jq 通过该选项提供了和宿主脚本语言交互的能力。该选项将值(v)绑定到一个变量(a)上。在后面的 filter 中可以直接通过变量引用这个值。例如,filter '.$a'表示查询属性名称等于变量 a 的值的属性。
jq 表达式从图 1 的 jq 帮助中我们可以看出,在调用 jq 处理 JSON 数据时有一个必须的部分"jq filters". 实际上,jq 内部构建了一个简易的,功能完备的语言系统。用户在使用 jq 时,需要使用 jq 支持的语法来构建表达式(filters)并将其传给 jq。 jq 根据语法规则解析表达式并应用在输入的 JSON 数据上从而得到需要的结果。
jq 表达式支持串行化操作。一个复杂的表达式可以有多个简单的,以"|"符号分割的,串行化执行的表达式组成。每个表达式以其前边表达式的结果为输入。例如:有 JSON 数据{"name":{"firstname":"Tom","lastname":"Clancy"}}。我们要查询 lastname 属性可以使用表达式'.name|.lastname'。为了方便处理 JSON 数据,jq 提供了以下几点特性支持:
jq 内建了对 JSON 标准中各种数据类型的支持
jq 内建了多种操作符和函数来进行数据的选择和转换。
jq 支持自定义函数和模块化系统。我们可以自定义自己的函数库,并在 jq 表达式中引用。
基础表达式