文章目录
- jq工具介绍
- `jq --help`解读
- 英文
- 中文
- 使用示例
- 1. 使用最简单的过滤器。将输入复制到输出,不做任何修改(除了格式化)
- 2. 使用 `-c` 选项进行紧凑输出而非美化输出
- 3. 使用 `-n` 选项以 `null` 作为单一输入值(用于创建新json,不必提供json输入)
- 4. 使用 `-e` 选项设置基于输出的退出状态代码
- 5. 使用 `-s` 选项将所有输入读取(slurp)到一个数组中,并对其应用过滤器
- 6. 使用 `-r` 选项输出原始字符串,而非JSON文本
- 7. 使用 `--arg a v` 设置变量 `$a` 的值为 `<v>`
- 8. 使用 `--argjson a v` 设置变量 `$a` 的值为 JSON `<v>`
- 9. 使用 `--slurpfile a f` 设置变量 `$a` 为从 `<f>` 读取的 JSON 文本数组
- 注意,对于命令`jq -n --slurpfile data xxx.json '. + {"data": $data}'`,如果不加`-n`参数,执行将会卡住(hanging)
- 解决方法
- 方法1:加`-n`参数
- 方法2:管道指定输入json
- 方法3:用here string语法指定输入json
- 10. 使用 `--rawfile a f` 设置变量 `$a` 为 `<f>` 内容的字符串
- 示例
jq工具介绍
jq
是一个轻量级且灵活的命令行 JSON 处理工具。它可以用来解析、过滤、查询和操作 JSON 数据。
以下是 jq
的一些主要特性:
-
读取 JSON:你可以使用
jq
来读取 JSON 文件或者其他 JSON 数据源,并将数据转换为易于阅读的格式。 -
过滤和查询:
jq
提供了强大的过滤和查询功能,你可以使用它来提取和查看 JSON 数据中的特定部分。例如,你可以使用.foo.bar
来提取名为 “foo” 的对象中名为 “bar” 的字段。 -
数据操作:你可以使用
jq
来修改 JSON 数据。例如,你可以添加、删除或更改字段,或者你可以将数据从一种形式转换为另一种形式。 -
脚本和自动化:由于
jq
是一个命令行工具,所以你可以在脚本或者自动化任务中使用它来处理 JSON 数据。 -
强大的函数库:
jq
有一个强大的函数库,可以用来对 JSON 数据进行各种复杂的操作。例如,你可以使用map()
函数来处理数组,或者你可以使用select()
函数来过滤数据。
参考文章:Linux shell jq工具(shell读取json、shell脚本读取json、shell json、json工具)
jq --help
解读
英文
root@ky:/# jq --help
jq - commandline JSON processor [version 1.6]
Usage: jq [options] <jq filter> [file...]
jq [options] --args <jq filter> [strings...]
jq [options] --jsonargs <jq filter> [JSON_TEXTS...]
jq is a tool for processing JSON inputs, applying the given filter to
its JSON text inputs and producing the filter's results as JSON on
standard output.
The simplest filter is ., which copies jq's input to its output
unmodified (except for formatting, but note that IEEE754 is used
for number representation internally, with all that that implies).
For more advanced filters see the jq(1) manpage ("man jq")
and/or https://stedolan.github.io/jq
Example:
$ echo '{"foo": 0}' | jq .
{
"foo": 0
}
Some of the options include:
-c compact instead of pretty-printed output;
-n use `null` as the single input value;
-e set the exit status code based on the output;
-s read (slurp) all inputs into an array; apply filter to it;
-r output raw strings, not JSON texts;
-R read raw strings, not JSON texts;
-C colorize JSON;
-M monochrome (don't colorize JSON);
-S sort keys of objects on output;
--tab use tabs for indentation;
--arg a v set variable $a to value <v>;
--argjson a v set variable $a to JSON value <v>;
--slurpfile a f set variable $a to an array of JSON texts read from <f>;
--rawfile a f set variable $a to a string consisting of the contents of <f>;
--args remaining arguments are string arguments, not files;
--jsonargs remaining arguments are JSON arguments, not files;
-- terminates argument processing;
Named arguments are also available as $ARGS.named[], while
positional arguments are available as $ARGS.positional[].
See the manpage for more options.
中文
root@ky:/# /ky/tools/jq/jq-linux64 --help
jq - 命令行JSON处理器 [版本 1.6]
使用方法: jq [选项] <jq过滤器> [文件...]
jq [选项] --args <jq过滤器> [字符串...]
jq [选项] --jsonargs <jq过滤器> [JSON_TEXTS...]
jq是一个用于处理JSON输入的工具,将给定的过滤器应用于其JSON文本输入,并在标准输出上产生过滤器的结果作为JSON。
最简单的过滤器是.,它将jq的输入复制到其输出中无修改(除了格式化,但请注意,内部使用IEEE754来表示数字,这意味着所有相关内容)。
更多高级过滤器,请参见jq(1)手册页("man jq")和/或https://stedolan.github.io/jq
示例:
$ echo '{"foo": 0}' | jq .
{
"foo": 0
}
一些选项包括:
-c 输出紧凑而不是美观打印的输出;
-n 使用`null`作为单个输入值;
-e 根据输出设置退出状态码;
-s 读取(slurp)所有输入到数组中;对其应用过滤器;
-r 输出原始字符串,而不是JSON文本;
-R 读取原始字符串,而不是JSON文本;
-C 为JSON着色;
-M 单色(不为JSON着色);
-S 在输出上对对象的键进行排序;
--tab 使用制表符进行缩进;
--arg a v 设置变量$a的值为<v>;
--argjson a v 设置变量$a的JSON值为<v>;
--slurpfile a f 设置变量$a为从<f>读取的JSON文本数组;
--rawfile a f 设置变量$a为<f>内容组成的字符串;
--args 剩余参数是字符串参数,而不是文件;
--jsonargs 剩余参数是JSON参数,而不是文件;
-- 结束参数处理;
命名参数也可以作为$ARGS.named[]使用,而位置参数可以作为$ARGS.positional[]使用。
查看手册页以获取更多选项。
使用示例
假设我们有一个/ky_cont_img/hw/ky_ai_cont.json
:
{
"conts": [
{
"contName": "ky_obj",
"imgPkgName": "ky_ascend_obj_v1.1.tar",
"imgName": "ky_ascend_obj",
"imgTag": "v1.1"
},
{
"contName": "ky_obj2",
"imgPkgName": "ky_ascend_obj_v1.1.tar",
"imgName": "ky_ascend_obj",
"imgTag": "v1.1"
}
]
}
1. 使用最简单的过滤器。将输入复制到输出,不做任何修改(除了格式化)
echo '{"foo": 0}' | jq .
在jq中,
.
或者说点表示的是当前处理的JSON数据。当用.
作为过滤器时,意思是把输入的JSON数据原样输出,不做任何修改。例如,在命令
echo '{"foo": 0}' | jq .
中,jq .
的作用就是将输入的{"foo": 0}
这个JSON对象直接输出。另外,还可以使用
.
来访问JSON对象的属性。例如,如果想获取这个JSON对象的 “foo” 属性,可以使用.foo
作为过滤器:echo '{"foo": 0}' | jq .foo
,这条命令将会输出0
。
2. 使用 -c
选项进行紧凑输出而非美化输出
echo '{"foo": 0, "bar": 1}' | jq -c .
3. 使用 -n
选项以 null
作为单一输入值(用于创建新json,不必提供json输入)
-n
选项的作用是使jq以 null
作为单一输入值。在默认情况下,jq会期望从标准输入或文件中读取JSON数据。然而,如果想生成新的JSON,而不是对现有的JSON进行处理,那么 -n
选项就会非常有用。
例如,假设想创建一个包含特定键值对的新JSON对象,你可以使用以下命令:
jq -n '{ "foo": "bar", "baz": 42 }'
这个命令将输出:
{
"foo": "bar",
"baz": 42
}
因此,尽管 -n
选项看起来像是让输入为 null
,但它实际上更多的是为了可以创建新的JSON,而不必先提供一个现有的JSON输入。
4. 使用 -e
选项设置基于输出的退出状态代码
-e
选项的作用是设置基于输出的退出状态代码。这主要在脚本编写和自动化任务中使用。
当你使用 -e
选项时,如果jq的最后一个过滤器产生的结果为空(null或者false),那么jq命令将返回非零的退出状态码。否则,如果最后一个过滤器产生的结果非空(也就是有任何有效的JSON值),那么jq命令将返回零的退出状态码。
例如,下面这个命令:
echo '{"foo": 0}' | /ky/tools/jq/jq-linux64 -e .bar
因为 “.bar” 在输入的JSON对象中不存在,所以过滤器的结果是 null
,jq命令会返回非零的退出状态码。
反之如果执行:
echo '{"foo": 100}' | /ky/tools/jq/jq-linux64 -e .foo
jq命令会返回值为零的退出状态码(表示命令正常执行)。
这种特性通常用于错误检查或条件判断。比如,你可以通过检查jq命令的退出状态来判断某个JSON对象是否包含某个属性。
5. 使用 -s
选项将所有输入读取(slurp)到一个数组中,并对其应用过滤器
如果直接使用 jq .
命令来处理以下数据:
echo -e '{"name": "Alice"}\n{"name": "Bob"}' | jq .
输出结果如下:
{"name": "Alice"}
{"name": "Bob"}
然而,如果你想将所有输入数据看作一个整体来处理,你可以使用 jq -s .
命令,像这样:
echo -e '{"name": "Alice"}\n{"name": "Bob"}' | jq -s .
输出结果如下:
[
{"name": "Alice"},
{"name": "Bob"}
]
在这个例子中,-s
选项让jq把所有输入数据合并成了一个数组,然后再对这个数组进行处理。这里 -e
是 echo
命令的一个参数,用于开启转义字符的解析,这样 \n
就能被识别为换行符,从而分隔多行的 JSON 数据。
6. 使用 -r
选项输出原始字符串,而非JSON文本
echo '{"foo": "bar"}' | jq -r .foo
echo '{"foo": "bar"}' | jq .foo
7. 使用 --arg a v
设置变量 $a
的值为 <v>
echo '{}' | jq --arg foo bar '. + {($foo): "value"}'
--arg a v
是 jq 命令的一个选项,它允许你在 jq 脚本中定义一个变量,并给它赋值。这个选项可以用来将 shell 脚本中的变量传递到 jq 脚本中。
例如(<<<
是here string语法,用于将一个字符串传给jq命令,与管道类似):
jq --arg myVar value '. + {new_key: $myVar}' <<< '{}'
或者:
echo '{}' | jq --arg myVar value '. + {new_key: $myVar}'
这(两)个命令会创建一个新的 JSON 对象 {}
,然后添加一个新的键值对,其中键是 “new_key”,值是由 $myVar
变量指定的,即 “value”。所以,这个命令的输出结果是:
{
"new_key": "value"
}
在这个例子中,--arg myVar value
的作用是在 jq 脚本中定义一个名为 myVar
的变量,并将其值设置为 “value”。然后,. + {new_key: $myVar}
这部分是 jq 脚本,它使用了刚刚定义的 myVar
变量。
8. 使用 --argjson a v
设置变量 $a
的值为 JSON <v>
echo '{}' | jq --argjson foo '{"bar": "baz"}' '. + $foo'
--argjson a v
是 jq 命令的一个选项,它允许在 jq 脚本中定义一个变量,并将一个 JSON 字符串赋值给它。这个选项在你需要将包含复杂数据(如数组或对象)的 JSON 字符串传递给 jq 脚本时非常有用。
例如:
jq --argjson myVar '{"key": "value"}' '. + {"foo": $myVar}' <<< '{}'
这个命令会创建一个新的 JSON 对象 {}
,然后添加一个新的键值对到foo字段下,其中键是 “key”,值是由 $myVar
变量指定的,即 “value”。所以,这个命令的输出结果是:
{
"foo": {
"key": "value"
}
}
在这个例子中,--argjson myVar '{"key": "value"}'
的作用是在 jq 脚本中定义一个名为 myVar
的变量,并将其值设置为一个 JSON 对象 {"key": "value"}
。然后,+ {"foo": $myVar}
这部分是 jq 脚本,它使用了刚刚定义的 myVar
变量。
与 --arg
不同,--argjson
会将输入字符串解析为 JSON,而不是将其视为普通的字符串。这使得你可以方便地处理包含数组或对象的复杂 JSON 数据。
9. 使用 --slurpfile a f
设置变量 $a
为从 <f>
读取的 JSON 文本数组
--slurpfile a f
是 jq
命令的一个选项,它允许你从文件中读取 JSON 数据,并将数据存储到一个数组变量中。这个选项在你需要处理存储在文件中的大量 JSON 数据时非常有用。
例如,以下命令中:
jq -n --slurpfile data /ky_cont_img/hw/ky_ai_cont.json '. + {"data": $data}'
--slurpfile data /ky_cont_img/hw/ky_ai_cont.json
首先会从 /ky_cont_img/hw/ky_ai_cont.json
这个文件中读取所有的 JSON 数据,然后将这些数据合并成一个数组,并将这个数组赋值给 data
变量。
接下来,. + {"data": $data}
这部分是 jq 脚本,它创建了一个新的 JSON 对象,并添加了一个新的键值对,其中键是 “data”,值是由 $data
变量指定的,即刚刚从文件中读取的 JSON 数组。
所以,如果 /ky_cont_img/hw/ky_ai_cont.json
这个文件的内容是 [{"name": "Alice"}, {"name": "Bob"}]
,那么上述命令的输出结果就会是:
{
"data": [
{
"name": "Alice"
},
{
"name": "Bob"
}
]
}
注意,对于命令jq -n --slurpfile data xxx.json '. + {"data": $data}'
,如果不加-n
参数,执行将会卡住(hanging)
/ky/tools/jq/jq-linux64 --slurpfile data /ky_cont_img/hw/ky_ai_cont.json '. + {"data": $data}'
解决方法
解决办法是加-n
参数(表示无输入),或者指定输入:
方法1:加-n
参数
/ky/tools/jq/jq-linux64 -n --slurpfile data /ky_cont_img/hw/ky_ai_cont.json '. + {"data": $data}'
方法2:管道指定输入json
echo '{}' | /ky/tools/jq/jq-linux64 --slurpfile data /ky_cont_img/hw/ky_ai_cont.json '. + {"data": $data}'
方法3:用here string语法指定输入json
/ky/tools/jq/jq-linux64 --slurpfile data /ky_cont_img/hw/ky_ai_cont.json '. + {"data": $data}' <<< '{}'
10. 使用 --rawfile a f
设置变量 $a
为 <f>
内容的字符串
--rawfile a f
是 jq
命令的一个选项,用于将文件 <f>
的内容作为一个字符串读入到变量 $a
中。在这个命令中,a
是变量名,而 f
是你想要读取的文件的路径。
此选项的主要用途是允许你将一个文件的整个内容作为一个字符串处理,而不是试图将其解析为 JSON 数据。这在处理包含大量文本数据的文件时特别有用,因为你可以直接使用 jq
来处理这些文本,而不需要首先将它们转换为 JSON 格式。
例如,你可能有一个包含多行文本的文件,你想要将这个文件的内容添加到一个 JSON 对象中。使用 --rawfile
选项,你可以像这样做:
jq --rawfile text my_file.txt '. + {"text": $text}'
在这个例子中,my_file.txt
的内容会被读入到变量 $text
中,然后被添加到一个 JSON 对象中。最终的结果会是一个如下形式的 JSON 对象:
{
"text": "the entire content of my_file.txt"
}
在这个 JSON 对象中,text
键对应的值就是 my_file.txt
文件的完整内容。
示例
echo "I'm a test file!" >> test.txt
/ky/tools/jq/jq-linux64 -n --rawfile text test.txt '. + {"text": $text}'