[英]Parse 2 files based on key value and recreate another json file [JQ]
[英]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"
我可以使用类似的命令查询匹配wheel
的parts
$ 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.