json - jq 以不同的方式对 KEY 和 VALUES 进行排序 - 如何以相同的顺序枚举它们?

标签 json shell unix enumeration jq

我使用 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"

使用以下方法单独获取 VALUES:
curl http://test.te.com:8080/testApp/app/version | jq '.version' | jq '.[]'

输出(注意值的顺序如何与键名的顺序不对应;例如,第一个值 "user@test.com" 是键 "Built-By" 的值,而不是,正如我所期望的,对于第一个键, "Archiver-Version"):
"user@test.com"
"1634d38"
"sandbox"
"02-03-2014-13:41"
"testApp"

我试图将 KEYS 和 VALUES 分配给单独的数组,以便我可以迭代它们并以表格格式显示它们。

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

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

最佳答案

问题出在jq可能令人惊讶 默认行为 :

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

  • 换句话说:如果你使用 keys一次提取对象的键,然后 .[]要在另一个中提取其值,相应的输出元素可能不匹配。

    jq v1.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 , 使用 .[] 导致 无保证的枚举顺序 (使用了底层hash表的key排序,这是一个实现细节);如果您仍然必须使用 v1.3,您可以使用 to_entries方法如下所示。

    [v1.3+] to_entries/0 ,如 user2259432's helpful answer 中所用, 还列举了属性 按输入顺序 :
    # 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可以用来枚举key和value,就是仍然是生成稳定枚举顺序的可行解决方案 在并行键/值提取中,即使在 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
    

    A 注意事项 -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 之前,没有保证特定的顺序,但是导致了同样的问题。

    关于json - jq 以不同的方式对 KEY 和 VALUES 进行排序 - 如何以相同的顺序枚举它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23120359/

    相关文章:

    ios - AFHTTPSessionManager 发送 GET 请求 json 格式

    linux - Bash 脚本 : Can't set a variable using which

    python - 在 Pythonscript 中获取 Netcat 的输出

    iphone - 从 ruby​​ 运行 shell 脚本

    c++ - 带有命令行参数的 C++ Makefile 和 Bash 脚本

    linux - 从日期中获取月份和日期

    linux - 在 shell 脚本中将全局变量从子级导出到父级

    javascript - 如何使用 Javascript 从 URL 获取 JSON 字符串?

    c# - 从文件中动态读取资源

    android - 我应该怎么做才能将数据从 json 插入到 Android 中的 sqlite 中