2016-10-11 42 views
5

使用jq,如何選擇父對象(如果它包含滿足兩個過濾器要求的子對象)?使用jq通過搜索子鍵/值對來選擇父項

在這個例子中,我想選擇所有子網元素都有一個帶有「Name」鍵和值「TheName」的子標籤。我的例子有兩個子網。第一個在錯誤的關鍵中有「TheName」。第二個子網具有我正在查找的名稱/值對。即"Key": "Name", "Value": "TheName"

以下選擇其中一個標籤但沒有配對的指定值的子網。它返回兩個子網,而不是僅返回第二個子網。

jq '.Subnets[] | select(.Tags[].Value=="TheName")' output 

如何使用jq只選擇具有名稱/值對的子網我正在尋找?

{ 
    "Subnets": [ 
     { 
      "VpcId": "vpc-12345678", 
      "SubnetId": "subnet-1234567a", 
      "Tags": [ 
       { 
        "Key": "IgnoreThis", 
        "Value": "TheName" 
       }, 
       { 
        "Key": "Name", 
        "Value": "NotTheName" 
       } 
      ] 
     }, 
     { 
      "VpcId": "vpc-12345678", 
      "SubnetId": "subnet-1234567b", 
      "Tags": [ 
       { 
        "Key": "IgnoreThis", 
        "Value": "ignore" 
       }, 
       { 
        "Key": "Name", 
        "Value": "TheName" 
       } 
      ] 
     } 
    ] 
} 

所需的輸出將是:

{ 
    "VpcId": "vpc-12345678", 
    "SubnetId": "subnet-1234567b", 
    "Tags": [ 
     { 
      "Key": "IgnoreThis", 
      "Value": "ignore" 
     }, 
     { 
      "Key": "Name", 
      "Value": "TheName" 
     } 
    ] 
} 
+0

最喜歡的寫得好的Unix命令,'jq'可以讀取的文件名參數,以使得['cat'是無用](HTTP的溶液:// WWW .iki.fi/era/unix/award.html) – tripleee

回答

4

假設你的JQ有any/2,一個簡單而有效的解決辦法是:

.Subnets[] 
| select(any (.Tags[]; .Key == "Name" and .Value == "TheName")) 

這將產生你想要的輸出,所以我這裏不再重複。

如果您JQ沒有any/2,我建議升級,但如果這是不方便或者不是一種選擇,你可以使用這個防守力:

def any(f;g): reduce f as $i (false; . or ($i|g)); 

附: any(str; cond)可以理解爲:'stream中是否有任何元素e,str,e|cond的值不是nullfalse?'

+0

真棒高峯!我不明白關於「任何」的文檔。關於jq的文檔和示例並不十分清楚。它需要更多像這樣的例子。希望問題標題能夠幫助別人找到你的答案! –

0

這裏是使用indices

.Subnets[] | select(.Tags | indices({Key:"Name", Value:"TheName"}) != []) 
相關問題