传入的json文件每行包含json数组,例如:
["a100","a101","a102","a103","a104","a105","a106","a107","a108"]
["a100","a102","a103","a106","a107","a108"]
["a100","a99"]
["a107","a108"]
“过滤器数组”为["a99","a101","a108"]
,因此我可以slurpfile
试图弄清楚如何仅打印“过滤器数组”内部的值,例如输出:
["a101","a108"]
["a108"]
["a99"]
["a108"]
答案 0 :(得分:3)
您可以将IN
功能从jq 1.6移植到1.5并使用:
def IN(s): any(s == .; .);
map(select(IN($filter_array[])))
或更短:
map(select(any($filter_array[]==.;.)))
答案 1 :(得分:1)
我可能会缺少一些更简单的解决方案,但以下方法可以实现:
map(select(. as $in | ["a99","a101","a108"] | contains([$in])))
用您的限定变量替换["a99","a101","a108"]
硬编码数组。
您可以try it here!
答案 2 :(得分:1)
在该示例中,对输入流中的数组进行了排序(以jq的sort
顺序排序),因此值得注意的是,在这种情况下,使用内置的bsearch
可以实现更有效的解决方案-或什至更好的是,在https://rosettacode.org/wiki/Set#Finite_Sets_of_JSON_Entities
intersection/2
的定义
为便于参考,此处为:
def intersection($A;$B):
def pop:
.[0] as $i
| .[1] as $j
| if $i == ($A|length) or $j == ($B|length) then empty
elif $A[$i] == $B[$j] then $A[$i], ([$i+1, $j+1] | pop)
elif $A[$i] < $B[$j] then [$i+1, $j] | pop
else [$i, $j+1] | pop
end;
[[0,0] | pop];
假定一个jq调用,例如:
jq -c --argjson filter '["a99","a101","a108"]' -f intersections.jq input.json
适当的过滤器为:
($filter | sort) as $sorted
| intersection(.; $sorted)
(当然,如果$ filter已按jq的排序顺序显示,则可以跳过初始排序,或用支票代替。)
["a101","a108"]
["a108"]
["a99"]
["a108"]
实际上,jq的内置sort
过滤器通常是如此之快,以至于使用上面定义的intersection
来对数组进行排序可能是值得的。