簡體   English   中英

jq | 獲取過濾路徑后的路徑值

[英]jq | get the paths value after filtered paths

假設我有以下 JSON:

{
  "A": {
    "ID": "something"
  },
  "B": {
    "ID": "something-else"
  },
  "C": {
    "ID": "something"
  },
  "D": {
    "E": {
      "ID": "something"
    }
  }
}

我想獲取所有包含"ID": "something"的路徑:

A.ID
C.ID
D.E.ID

嘗試這樣做我正在使用它來獲取所有具有ID密鑰的路徑

paths | select(.[-1] == "ID")

但 output 是:

[ "A", "ID" ]
[ "B", "ID" ]
[ "C", "ID" ]
[ "D", "E", "ID" ]

jq游樂場

應該可以使用getpath/1 收集符合您條件的路徑並提取每個路徑的值以查看是否符合您的條件

( paths | select(.[-1] == "ID")) as $p | 
  if getpath($p) == "something" then ( $p | join(".") ) else empty end

jqplay演示

另一種方法是使用--stream選項(或tostream函數),並同時檢查兩個條件:

jq -r --stream 'select(.[0][-1] == "ID" and .[1] == "something")[0] | join(".")'
A.ID
C.ID
D.E.ID

演示

一個更通用的解決方案是我編寫的名為jqg的腳本,它將展平 JSON 然后搜索它。 這不是一個完美的選擇,因為它不能在一次調用中同時搜索一個字符串的鍵和另一個字符串的值,但是這很容易通過將兩個調用與 pipe ( | ) 串在一起來完成。 從好的方面來說,您不必在每次搜索條件更改時都重寫它。

/tmp/so72977106.json - 樣本 JSON 與一堆額外的邊緣案例

{
  "A": {
    "ID": "something"
  },
  "B": {
    "ID": "something-else"
  },
  "C": {
    "ID": "something"
  },
  "C2": {
    "ID": {
      "name": "something"
    }
  },
  "C3": {
    "name": "ID"
  },
  "C4": {
    "XID": "something"
  },
  "C5": {
    "ID": "not-something"
  },
  "D": {
    "E": {
      "ID": "something"
    }
  }
}
$ jqg -k '\.ID$' /tmp/so72977106.json | jqg -vKr ^something$
A.ID
C.ID
D.E.ID

第一次調用僅搜索正則表達式\.ID$的鍵 ( -k ),第二次調用僅搜索正則表達式^something$的值 ( -v )。 第二次調用的 output 被修改為只打印出原始( -r )、扁平鍵( -K ); 否則它將產生有效的 JSON,例如第一次調用的 output:

$ jqg -k '\.ID$' /tmp/so72977106.json
{
  "A.ID": "something",
  "B.ID": "something-else",
  "C.ID": "something",
  "C5.ID": "not-something",
  "D.E.ID": "something"
}

注意:我是這個腳本的作者。

暫無
暫無

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

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