我们正在使用 Pentaho CTools 库构建一个网站,该库有一个图形仪表板编辑器,可以为仪表板的一部分编写 JSON 格式的文件。
我想在签入 git 之前对这些文件进行转换,以便按键对它们进行排序,然后按某些键的值对它们进行排序。目的是让差异变得更容易,因为编辑器有重新排列所有 json 字段的习惯。
例如,我们可能有这样的东西:
{
"components": {
"rows": [
{
"id": "CHARTS",
"name": "Charts",
"parent": "UnIqEiD",
"properties": [
{
"name": "Group",
"type": "Label",
"value": "Charts"
}
],
"type": "Label",
"typeDesc": "<i>Group</i>"
},
{
"id": "kjalajsdjf",
"meta_cdwSupport": "true",
"parent": "CHARTS",
"properties": [
{
"name": "name",
"type": "Id",
"value": "Value1"
},
{
"name": "title",
"type": "String",
"value": "Value2"
},
{
"name": "listeners",
"type": "Listeners",
"value": "[]"
},
...
我们能够
jq --sort-keys
(http://stedolan.github.io/jq/) 对所有键进行排序,但我很难找到如何使用 sort_by
函数进行排序某些特定元素按某些键的值排序(例如,在上面的示例中,按 properties.name
排序。有什么想法吗?
好的,在 IRC 频道的一些帮助下,我找到了答案。
基本上,它看起来像这样:
jq \
'.components.rows|=sort_by(.id)|.components.rows[].properties|=sort_by(.name)' \
file.json > out.json
选择正确的对象,
如果需要的话,走进数组,
然后
sort_by
单个值。
我正在尝试
sort_by(.components.rows.id)
但失败了。
|=
而不是 |
传递值而不是剥离它们。
这并不能回答问题,但这是另一种按属性/键排序的方法:
jq --sort-keys . my_file > sorted_file
-或-
jq -S . my_file > sorted_file
如果您在 JQ 查询中需要它,请选择:
def sort_keys:
(if (.|type!="object") then error("sort_keys: object expected") else . end)
|(.|keys) as $keys
|. as $o
|reduce $keys[] as $i ({};.[$i]=$o[$i]);
演示 json:(shell 脚本)
json='
{
"key_a": 500,
"key_e": 200,
"key_f": 100,
"key_b": 400,
"key_c": 300
}
'
命令:
echo "${json}" | jq -r --sort-keys
# or
echo "${json}" | jq -r 'to_entries | sort_by(.key) | from_entries'
输出:
{
"key_a": 500,
"key_b": 400,
"key_c": 300,
"key_e": 200,
"key_f": 100
}
命令:
echo "${json}" | jq -r 'to_entries | sort_by(.value) | from_entries'
输出:
{
"key_f": 100,
"key_e": 200,
"key_c": 300,
"key_b": 400,
"key_a": 500
}
演示 json:(shell 脚本)
json='
[
{"name":"zhang3", "age":40},
{"name":"li4", "age":28},
{"name":"wang5", "age":50},
{"name":"zhao6", "age":18}
]
'
按元素属性
age
值排序,取前3个元素。
命令:
echo "${json}" | jq -r 'sort_by(.age)|[limit(3;.[])]'
输出:
[
{
"name": "zhao6",
"age": 18
},
{
"name": "li4",
"age": 28
},
{
"name": "zhang3",
"age": 40
}
]
只需使用
reverse
。
命令:
echo "${json}" | jq -r 'sort_by(.age)|reverse|[limit(3;.[])]'
输出:
[
{
"name": "wang5",
"age": 50
},
{
"name": "zhang3",
"age": 40
},
{
"name": "li4",
"age": 28
}
]