9

我使用 curl 命令以 JSON 格式获取 REST 输出,如下所示

使用以下方法单独获取 KEY 名称:

curl http://test.te:8080/testApp/app/version | jq '.version' | jq '. | keys'

输出:

"Archiver-Version",
"Build-Id",
"Build-Jdk",
"Build-Number",
"Build-Tag",
"Built-By"

使用以下方法单独获取价值:

curl http://test.te.com:8080/testApp/app/version | jq '.version' | jq '.[]'

输出(请注意值的顺序如何与键名的顺序不对应;例如,第一个值 ,"user@test.com"是 key 的值"Built-By",而不是我所期望的第一个键的值"Archiver-Version"):

"user@test.com"
"1634d38"
"sandbox"
"02-03-2014-13:41"
"testApp"

我正在尝试将 KEYS 和 VALUES 分配给单独的数组,以便我可以遍历它们并以表格格式显示它们。

但是这两个命令的排序方式不同,我不能直接分配值和键。

无论如何要更改 KEYS 和 VALUES 的排序以使两者相同?

4

3 回答 3

16

问题源于jq可能令人惊讶的默认行为

  • keys枚举按字母顺序排序的键。
  • .[]根据键的输入顺序枚举值[1]

换句话说:如果您在一次传递keys中提取对象的,然后在另一次传递.[]中提取其,则相应的输出元素可能不匹配。

jqv1.5引入了该keys_unsorted/0功能,可以实现简单的解决方案:

# Sample input with unordered keys.
# Sorting the values results in the same order as sorting the keys,
# so the output order of values below implies the key enumeration order that was applied.
json='{ "c":3, "a":1, "b":2 }'

按输入顺序打印,使用keys_unsorted/0

$ echo "$json" | jq -r 'keys_unsorted[]'
c
a
b

按输入顺序打印,这[]总是:

$ echo "$json" | jq -r '.[]'
3
1
2

警告:直到v1.3版本,使用.[]导致没有保证的枚举顺序(使用了底层哈希表的键排序,这是一个实现细节);如果您仍然必须使用 v1.3,您可以使用to_entries如下所示的方法。


[v1.3+] to_entries/0,如user2259432 的有用答案中所使用的,还按输入顺序枚举属性:

# Extract keys
$ echo "$json" | jq -r 'to_entries | map(.key)[]'
c
a
b
# Extract values
$ echo "$json" | jq -r 'to_entries | map(.value)[]'
3
1
2

警告在 v1.5 之前,以按键to_entries/0排序的顺序输出键值对。

但是,由于to_entries/0可用于枚举键和值,因此即使在 v1.5 之前的版本中,它仍然是在并行键/值提取中生成稳定枚举顺序的可行解决方案


[v1.3+]相比之下,如果您想按键排序的顺序进行枚举

按字母顺序打印,使用keys/0

$ echo "$json" | jq -r 'keys[]'
a
b
c

按字母顺序键打印

$ echo "$json" | jq -r 'keys[] as $k | .[$k]'
1
2
3

一个警告重新-S/--sort-keys

此选项仅适用于整个对象输出

$ echo "$json" | jq -Sc '.'
{"a":1,"b":2,"c":3}  # Sorted by key

当您使用运算符或函数访问对象的内部时,它不适用:

$ echo "$json" | jq -S '.[]' # !! -S doesn't apply, because [] always uses input order
3
1
2

[1] 在 v1.5 之前,不保证特定的顺序,但是会导致同样的问题。

于 2017-02-19T07:01:51.730 回答
13

jq has an option to sort the keys. See http://stedolan.github.io/jq/manual/#Invokingjq

--sort-keys / -S:

Output the fields of each object with the keys in sorted order.

However the current released version (1.3) of jq doesn't have this enhancement yet, you'll need to compile jq via latest code from it's master branch. See http://stedolan.github.io/jq/download/ , the "From source on Linux or OS X" section.

For a complete history and details of this feature, see issue #79 "Option or function to sort object members by name" https://github.com/stedolan/jq/issues/79

于 2014-04-23T04:28:44.527 回答
6

你也可以

$ echo '{"a":0, "b":1}' | jq -c 'to_entries|map([.key, .value])|map(.[])'
["a",0,"b",1]
于 2014-06-19T20:13:46.057 回答