[英]How can I replace a null value in a json document by a specific value with jq?
I have a json file that contains null
s as values for some keys, which I would like to replace with some specific value. 我有一个json文件,其中包含
null
作为某些键的值,我想将其替换为某些特定值。
Given this input: 鉴于此输入:
{
"id": null,
"rows": [
{
"panels": [
{
"title": "Panel1",
"datasource": null
},
{
"title": "Panel2",
"datasource": null
}
]
}
]
}
I would like to have 我想拥有
{
"id": null,
"rows": [
{
"panels": [
{
"title": "Panel1",
"datasource": "mydb"
},
{
"title": "Panel2",
"datasource": "mydb"
}
]
}
]
}
What I currently use is 我目前使用的是
sed 's/"datasource": null/"datasource": "mydb"/'
This produces the output I need, but I keep thinking that it is a shame to use sed
for this job, when there are tools like jq
that can work on JSON in a much better way. 这产生了我需要的输出,但是当有
jq
类的工具可以以更好的方式处理JSON时,我一直认为使用sed
来完成这项工作实在可惜。
First you need to identify the objects you want to update. 首先,您需要确定要更新的对象。 Since you want to set the null datasources of the panels to
"mydb"
, you could do this: 由于要将面板的空数据源设置为
"mydb"
,可以执行以下操作:
$ jq '.rows[].panels[].datasource //= "mydb"' input.json
If you want to update any datasource
property on any object at any level, you could use ..
to recursively search for them. 如果要在任何级别更新任何对象上的任何
datasource
属性,则可以使用..
递归搜索它们。
$ jq '(.. | select(objects | has("datasource"))).datasource //= "mydb"' input.json
For the record, it is also quite easy to change all key values that are null (no matter where they occur) to some other value. 作为记录,将所有为空的键值(无论它们出现在何处)更改为其他值也很容易。 Versions of jq > 1.5 include a jq-defined filter, walk/1, which can be used (eg by copying and pasting) in other versions of jq as well.
jq> 1.5的版本包括jq定义的过滤器walk / 1,它也可以在其他jq版本中使用(例如,通过复制和粘贴)。
For example, to change all key values that are null to 0 using walk/1: 例如,要使用walk / 1将所有null的键值更改为0:
walk(if type == "object" then with_entries(.value //= 0) else . end)
Here is the jq-provided definition of walk/1: 这是jq提供的walk / 1定义:
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;
Here is a solution which uses tostream , reduce and setpath to set any leaf datasource
attribute whose value is null
to "mydb"
. 这是一个使用tostream , reduce和setpath来将任何值为
null
叶子datasource
属性设置为"mydb"
。
reduce (tostream|select(length==2)) as [$p,$v] (
.
; if $p[-1] == "datasource" and $v == null then setpath($p; "mydb") else . end
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.