我有一个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选择原始阵列的两个单独元素。