簡體   English   中英

使用 jq 根據另一個鍵名更新 json 的鍵

[英]Updating key of json based on another key name using jq

我有以下JSON文件,需要更換tbd-premium-在任務的值當且僅當由被german和任務的價值開始與tbd-

{
    "vehicle": {
        "maintenance": [
            {
                "parts": "wheel",
                "size": ["one", "two"]
            },
            {
                "task": "tbd-service-oil",
                "car": {
                    "german": {
                        "audi": ["Synthetic"]
                    }
                },
                "some": ["other"]
            },
            {
                "task": "service-oil",
                "honda": {
                    "japan": {
                        "oil": ["regular"]
                    }
                }
            }
        ],
        "repair": [
            {
                "parts": "wheel",
                "size": ["one", "two"]
            },
            {
                "task": "tbd-engine-repair",
                "car": {
                    "german": {
                        "engine": ["6-cyl"]
                    }
                }
            },
            {
                "task": "engine-repair",
                "car": {
                    "german": {
                        "engine": ["4-cyl"]
                    }
                }
            }
        ]
        
    }
}

需要將上面的 json 文件更新為:

{
    "vehicle": {
        "maintenance": [
            {
                "parts": "wheel",
                "size": ["one", "two"]
            },
            {
                "task": "premium-service-oil", ## update this b'cos there is "german" under "car" and task's value had prefix "tbd-"
                "car": {
                    "german": {
                        "audi": ["Synthetic"]
                    }
                },
                "some": ["other"]
            },
            {
                "task": "service-oil",
                "honda": {
                    "japan": {
                        "oil": ["regular"]
                    }
                }
            }
        ],
        "repair": [
            {
                "parts": "wheel",
                "size": ["one", "two"]
            },
            {
                "task": "premium-engine-repair", ## update this b'cos there is "german" under "car" and task's value had prefix "tbd-"
                "car": {
                    "german": {
                        "engine": ["6-cyl"]
                    }
                }
            },
            {
                "task": "engine-repair", ### no need to update this as it don't have "tbd-" as prefix
                "car": {
                    "german": {
                        "engine": ["4-cyl"]
                    }
                }
            }
        ]
        
    }
}

到目前為止,我嘗試使用german作為鍵名獲取所有鍵,但我沒有成功

jq -c 'to_entries[] | select (.key.maintenance.car == "german") | [.key]' json
jq: error (at json:50): Cannot index string with string "maintenance"

我可以使用類似的命令查詢匹配wheelparts

$ jq -c 'to_entries[] | select (.value.maintenance[0].parts == "wheel") | [.key]'  json
["vehicle"]

更新:

我可以跳過檢查鍵是否有tbd- ,我可以去更新所有的鍵名而不管前綴。

這是使用walk的解決方案。 如果由於某種原因您想要一個更有針對性的解決方案(例如,一個不使用walk解決方案),那么相應地修改它應該很容易。

walk( if type=="object" and .task and (.task|startswith("tbd-")) and
         any(.[]; type=="object" and has("german"))
      then .task|=sub("tbd-"; "premium-")
      else . end )

如果您沒有 jq 1.6 ,它有 walk/1 ,請在 def walk 前面加上:

jq '
# Apply f to composite entities recursively, and to atoms
    def walk(f):
    . as $in
    | if type == "object" then
        reduce keys[] as $key
            ( {}; . + { ($key):  ($in[$key] | walk(f)) } ) | f
    elif type == "array" then map( walk(f) ) | f
    else f
    end;
  walk( if type=="object" and .task and (.task|startswith("tbd-")) and any(.[]; type=="object" and has("german")) then .task|=sub("tbd-"; "premium-") else . end )
' filename

來源: https : //github.com/stedolan/jq/issues/963#issuecomment-152783116

暫無
暫無

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

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