使用jq基于索引字符串列表的子集json



我有一个JSON数组,看起来像:

["a","b","c"]

我有一个bash变量,它是数组索引的列表,我想将其子集设置为

ix="0,2"

我想使用jq对这些索引进行子集设置,生成以下数组:

["a", "c"]

到目前为止,我已经能够将$ix解析为一个数组:

echo '["a","b","c"]' | jq --arg ix $ix '$ix | split(",") | map(tonumber)'

但是,当我尝试使用这个索引数组来子集["a","b","c"]时,我会遇到问题(以下工作都没有(:

echo '["a","b","c"]' | jq --arg ix $ix '. | $ix | split(",") | map(tonumber)'
echo '["a","b","c"]' | jq --arg ix $ix '. | ($ix | split(",") | map(tonumber))'
echo '["a","b","c"]' | jq --arg ix $ix '. | [$ix | split(",") | map(tonumber)]'
echo '["a","b","c"]' | jq --arg ix $ix '. | .[$ix | split(",") | map(tonumber)]'

我会做

jq --arg ix "$ix" '
($ix | split(",") | map(tonumber)) as [$a, $b] 
| .[$a:$b+1]
'

需要+1,因为阵列切片操作.[from;to]从(包括(到(排除(


变量赋值表达式... | exp as $var | ...使用表达式中的输入值,设置变量,然后将原始输入作为其输出。


另一种方法是:在bash中拆分ix,并将值作为位置参数传递:

IFS=, read -ra ixs <<< "$ix"
echo '["a","b","c"]' 
| jq --jsonargs '.[$ARGS.positional[0]:$ARGS.positional[1]+1]' "${ixs[@]}"

那么,您有一个巨大的数组和一个大的索引列表要提取吗?那么也许:

. as $some_huge_array |
reduce ($ix | split(",") | map(tonumber))[] as $i ([]; . + [$some_huge_array[$i]])

总结其中一些想法:

ix="0,3,4"
jq --argjson ixs "[$ix]" '. as $a | reduce $ixs[] as $i ([]; . + [$a[$i]])' <<END_INPUT
[1, 2, 3, 4, 5, 6, 7]
END_INPUT
[
1,
4,
5
]

正如@oguzismail所指出的,这里不需要reduce

jq --argjson ixs "[$ix]" '[.[$ixs[]]]'
  • $ixs数组
  • $ixs[]值流
  • .[ $ixs[] ]将输出$ixs的每个值的输入数组的值,作为值流
    • 这是一个隐式迭代
  • [ .[$ixs[]] ]将前一个流收集到一个数组中
$ cat test.json
>> ["a", "b", "c", "d", "e" ]
$ ix="0,2"
$ jq --arg ix "$ix" '($ix | split(",") | map(tonumber)) as [$a, $b] | .[$a:$b+1]' test.json
>> [
>>   "a",
>>   "b",
>>   "c"
>> ]

$ jq --arg ix "$ix" '($ix | split(",") | map(tonumber)) as [$a, $b] | .[$a,$b+1]' test.json
>> "a"
>> "d"

请注意[$a:$b+1][$a,$b+1]之间的输出有何不同。

[$a:$b+1]是生成子阵列的阵列切片鉴于CCD_ 15选择原始阵列的两个单独元素。

最新更新