在写 shell 脚本的时候遇到需要处理 json 数据,于是找到这款神奇的小工具 jq ,这里的 jq 不是 jquery 而是一款非常强大的 Linux 小工具,jq 的官网是:https://stedolan.github.io/jq/download/
首先,我们要使用它就需要先安装,可以去它的官网下载安装也可以使用下列命令进行安装
# Linux 使用 apt-get 安装
sudo apt-get install jq
# Mac OS 使用 brew 安装
brew install jq
当然我们如果写 shell 脚本的话可以先判断这个程序是否存在,不存在的话自动安装,如下是我写的一个判断方法,在 Mac OS 可使用,原理大致如下其他系统可以自行探索
# 判断 jq 是否安装
is_code_app_112233="jq"
if ! [ -x "$(command -v $is_code_app_112233)" ]; then
# echo "Error: $appName is not installed." >&2
if ! [ -x "$(command -v brew)" ]; then
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
fi
brew install "$is_code_app_112233"
fi
# TOOD …判断存在则继续执行…
安装后怎么使用呢?先看看它的指令
--version
输出 jq 版本并退出。
--seq
使用application/json-seqMIME类型方案在jq的输入和输出中分隔JSON文本。这意味着将在输出的每个值之前打印一个ASCII RS(记录分隔符)字符,并在每个输出之后打印一个ASCII LF(换行)字符。无法解析的输入JSON文本将被忽略(但会发出警告),并丢弃所有后续输入,直到下一个RS。此模式还解析不带--seq选项的jq的输出。
--stream
以流方式解析输入,输出路径和叶值数组(标量和空数组或空对象)。例如,"a"变[[],"a"],并且[[],"a",["b"]]成为[[0],[]],[[1],"a"],和[[1,0],"b"]。
这对于处理非常大的输入很有用。将此与过滤以及the reduce和foreach语法结合使用,可逐步减少大输入。
--slurp/ -s
不必为输入中的每个JSON对象运行筛选器,而是将整个输入流读入一个大数组,然后仅运行筛选器一次。
--raw-input/ -R
不要将输入解析JSON。相反,每一行文本都作为字符串传递到过滤器。如果与组合--slurp,则整个输入将作为单个长字符串传递到过滤器。
--null-input/ -n
根本不读任何输入!而是将过滤器null作为输入运行一次。当将jq用作简单计算器或从头开始构造JSON数据时,这很有用。
--compact-output/ -c
默认情况下,jq pretty-prints JSON输出。通过将每个JSON对象放在一行上,使用此选项将导致输出更紧凑。
--tab
为每个缩进级别用一个选项卡,而不是两个空格。
--indent n
使用给定的空格数(不超过8个)进行缩进。
--color-output/ -C 和 --monochrome-output/ -M
默认情况下,如果写入终端,jq将输出彩色的JSON。即使使用写入管道或文件-C,也可以强制其产生颜色,并使用禁用颜色-M。
可以使用JQ_COLORS环境变量配置颜色。
--ascii-output/ -a
jq通常将非ASCII Unicode代码点输出为UTF-8,即使输入将其指定为转义序列(例如“ \ u03bc”)也是如此。使用此选项,您可以强制jq产生纯ASCII输出,并用等效的转义序列替换每个非ASCII字符。
--unbuffered
在打印每个JSON对象之后刷新输出(如果将慢速数据源输送到jq并将jq的输出输送到其他位置,则很有用)。
--sort-keys/ -S
用键按顺序输出每个对象的字段。
--raw-output/ -r
使用此选项,如果过滤器的结果是字符串,则将其直接写入标准输出,而不是将其格式化为带引号的JSON字符串。这对于使jq过滤器与基于非JSON的系统进行通信很有用。
--join-output/ -j
就像,-r但是jq在每个输出之后不会打印换行符。
-f filename/ --from-file filename
从文件而不是从命令行读取过滤器,如awk的-f选项。您也可以使用“#”发表评论。
-Ldirectory/ -L directory
前置directory为模块搜索列表。如果使用此选项,则不使用内置搜索列表。请参阅下面的模块部分。
-e/ --exit-status
设置为0 JQ的退出状态,如果最后输出值既不false也不null,1,如果最后的输出值要么false或null或4,如果没有有效的结果是以往任何时候产生的。通常,如果存在任何使用问题或系统错误,jq退出时为2;如果存在jq程序编译错误,则退出3;如果运行jq程序,则退出0。
设置退出状态的另一种方法是使用halt_error内置功能。
--arg name value
此选项将值作为预定义变量传递给jq程序。如果使用来运行jq --arg foo bar,则$foo该程序在程序中可用并且具有值"bar"。请注意,value它将被视为字符串,因此--arg foo 123将绑定$foo到"123"。
命名参数也可用于jq程序$ARGS.named。
--argjson name JSON-text
此选项将JSON编码的值作为预定义变量传递给jq程序。如果使用来运行jq --argjson foo 123,则$foo该程序在程序中可用并且具有值123。
--slurpfile variable-name filename
此选项读取命名文件中的所有JSON文本,并将已解析的JSON值数组绑定到给定的全局变量。如果使用来运行jq --slurpfile foo bar,则$foo该程序中可用,并且有一个数组,其元素对应于名为的文件中的文本bar。
--rawfile variable-name filename
此选项读取命名的文件,并将其内容绑定到给定的全局变量。如果使用来运行jq --rawfile foo bar,则$foo该程序中可用,并且有一个字符串,其内容与名为的文件中的tex有关bar。
--argfile variable-name filename
不使用,使用--slurpfile代替。
(此选项类似于--slurpfile,但是当文件只有一个文本时,则使用该文本,否则使用文本数组--slurpfile。)
--args
其余参数是位置字符串参数。这些可作为到jq程序使用$ARGS.positional[]。
--jsonargs
其余参数是位置JSON文本参数。这些可作为到jq程序使用$ARGS.positional[]。
--run-tests [filename]
在给定文件或标准输入中运行测试。这必须是给出的最后一个选项,并且不支持所有前面的选项。输入由注释行,空行和程序行组成,后跟一个输入行,与预期一样多的输出行(每个输出一个)和一个终止的空行。编译失败测试从仅包含“ %% FAIL”的行开始,然后是包含要编译的程序的行,然后是包含要与实际值进行比较的错误消息的行。
我目录下有一个 app.json 如下:
{
"name": "test",
"AppID": "com.test",
"DisplayName": "demo",
"Version": "1.0",
"Build": 1,
}
我用 jq 获取 name 可以这么来写:
jq -c .name ./app.json
你会发现这个参数是获取到了但是怎么带了引号,jq 如何去掉引号获取呢?(现在我演示一下如何获取一个类似:{"name":"zmide","id":1234} 中获取 name 并赋值到 shell 变量上 )
# 去掉引号获取可以使用 -r 模式,这里我用了管道符代替文件了
echo '{"name":"zmide","id":1234}' | jq -r .name
# 将获取到的值赋值到 name 变量
name=`echo '{"name":"zmide","id":1234}' | jq -r .name`
echo $name
好了这个小工具的基本使用我就讲到这里,更多强大的使用方法快去官网手册一探究竟吧:https://stedolan.github.io/jq/manual/