简体   繁体   English

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

[英]jq 1.5 print items from array that is inside another array

Incoming json file contains json array per row eg: 传入的json文件每行包含json数组,例如:

["a100","a101","a102","a103","a104","a105","a106","a107","a108"]
["a100","a102","a103","a106","a107","a108"]
["a100","a99"]
["a107","a108"]

a "filter array" would be ["a99","a101","a108"] so I can slurpfile it 一个“过滤器数组”将是["a99","a101","a108"]因此我可以slurpfile其文件化

Trying to figure out how to print only values that are inside "filter array", eg the output: 试图弄清楚如何仅打印“过滤器数组”内部的值,例如输出:

["a101","a108"]
["a108"]
["a99"]
["a108"]

You can port IN function from jq 1.6 to 1.5 and use: 您可以从jq 1.6到1.5移植IN功能并使用:

def IN(s): any(s == .; .);
map(select(IN($filter_array[])))

Or even shorter: 甚至更短:

map(select(any($filter_array[]==.;.)))

I might be missing some simpler solution, but the following works : 我可能缺少一些更简单的解决方案,但以下工作原理:

map(select(. as $in | ["a99","a101","a108"] | contains([$in])))

Replace the ["a99","a101","a108"] hardcoded array by your slurped variable. 用您的["a99","a101","a108"]替换["a99","a101","a108"]硬编码数组。

You can try it here ! 您可以在这里尝试

In the example, the arrays in the input stream are sorted (in jq's sort order), so it is worth noting that in such cases, a more efficient solution is possible using the bsearch built-in, or perhaps even better, the definition of intersection/2 given at https://rosettacode.org/wiki/Set#Finite_Sets_of_JSON_Entities 在该示例中,输入流中的数组进行了排序(按jq的sort顺序),因此值得注意的是,在这种情况下,可以使用内置的bsearch甚至更好的bsearch定义来实现更有效的解决方案。 https://rosettacode.org/wiki/Set#Finite_Sets_of_JSON_Entities给出的intersection/2

For ease of reference, here it is: 为了便于参考,此处为:

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];

Assuming a jq invocation such as: 假设有一个jq调用,例如:

jq -c --argjson filter '["a99","a101","a108"]' -f intersections.jq input.json

an appropriate filter would be: 合适的过滤器为:

($filter | sort) as $sorted
| intersection(.; $sorted)

(Of course if $filter is already presented in jq's sort order, then the initial sort can be skipped, or replaced by a check.) (当然,如果$ filter已按jq的排序顺序显示,则可以跳过初始排序,或由检查代替。)

Output 输出量

["a101","a108"]
["a108"]
["a99"]
["a108"]

Unsorted arrays 未排序的数组

In practice, jq's builtin sort filter is usually so fast that it might be worthwhile simply sorting the arrays in order to use intersection as defined above. 实际上,jq的内置sort过滤器通常是如此之快,以至于需要使用上面定义的intersection对数组进行简单排序可能是值得的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM