簡體   English   中英

jq 1.5從另一個數組中的數組打印項目

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

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

您可以從jq 1.6到1.5移植IN功能並使用:

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

甚至更短:

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

我可能缺少一些更簡單的解決方案,但以下工作原理:

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

用您的["a99","a101","a108"]替換["a99","a101","a108"]硬編碼數組。

您可以在這里嘗試

在該示例中,輸入流中的數組進行了排序(按jq的sort順序),因此值得注意的是,在這種情況下,可以使用內置的bsearch甚至更好的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對數組進行簡單排序可能是值得的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM