jq 1.5从另一个数组中的数组打印项目

时间:2019-05-16 15:39:02

标签: json jq

传入的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"]

3 个答案:

答案 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来对数组进行排序可能是值得的。