簡體   English   中英

使用 JQ 刪除具有某些鍵值對的父元素

[英]Remove parent elements with certain key-value pairs using JQ

我需要根據某些鍵值從 json 文件中刪除元素。 這是我要處理的文件。

{
  "element1": "Test Element 1",
  "element2": {
    "tags": "internal",
    "data": {
      "data1": "Test Data 1",
      "data2": "Test Data 2"
    }
  },
  "element3": {
    "function1": {
      "tags": [
        "new",
        "internal"
      ]
    },
    "data3": "Test Data 3",
    "data4": "Test Data 4"
  },
  "element4": {
    "function2": {
      "tags": "new"
    },
    "data5": "Test Data 5"
  }
}

我想刪除所有具有“內部”值的“標簽”的元素。 所以結果應該是這樣的:

{
  "element1": "Test Element 1",
  "element4": {
    "function2": {
      "tags": "new"
    },
    "data5": "Test Data 5"
  }
}

我嘗試了各種方法,但我只是沒有使用 jq 完成它。 有任何想法嗎? 謝謝。

只是為了增加一些復雜性。 假設 json 是:

{
  "element1": "Test Element 1",
  "element2": {
    "tags": "internal",
    "data": {
      "data1": "Test Data 1",
      "data2": "Test Data 2"
    }
  },
  "element3": {
    "function1": {
      "tags": [
        "new",
        "internal"
      ]
    },
    "data3": "Test Data 3",
    "data4": "Test Data 4"
  },
  "element4": {
    "function2": {
      "tags": "new"
    },
    "data5": "Test Data 5"
  },
  "structure1" : {
    "substructure1": {
      "element5": "Test Element 5",
      "element6": {
        "tags": "internal",
        "data6": "Test Data 6"
      }
    }
  }
}

我想得到

{
  "element1": "Test Element 1",
  "element4": {
    "function2": {
      "tags": "new"
    },
    "data5": "Test Data 5"
  },
  "structure1" : {
    "substructure1": {
      "element5": "Test Element 5",
    }
  }
}

不容易,只有使用下面的復雜 boolean 表達式才能以可靠的方式找到在某處具有tags鍵的元素,其值為字符串internal或元素為字符串internal的數組。

找到后,可以使用內置的del刪除它們。

del(.[] | first(select(recurse
  | objects
  | has("tags") and (.tags
    | . == "internal" or (
      type == "array" and index("internal")
    )
  )
)))

在線演示

為了清楚起見,以下解決方案是使用幫助程序 function 編寫的。 幫助器 function 使用any來提高效率,並定義為增加一點通用性。

要了解解決方案,了解with_entries和中綴//運算符將很有幫助,這兩者都在 jq 手冊中進行了說明。

# Does the incoming JSON value contain an object which has a .tags
# value that is equal to $value or to an array containing $value ?
def hasTag($value):
  any(.. | select(type=="object") | .tags;
      . == $value or (type == "array" and index($value)));

假設頂層 JSON 實體是 JSON object,我們現在可以簡單地寫:

with_entries( select( .value | hasTag("internal") | not) )

我想我想出了如何解決更復雜的情況。 我現在正在運行:

walk(if type == "object" and has("tags") and (.tags  | . == "internal" or (type == "array" and index("internal"))) then del(.) else . end) | delpaths([paths as $path | select(getpath($path) == null) | $path])

這將刪除所有包含“內部”作為“標簽”的元素。

暫無
暫無

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

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