在以下 json 文件中,
{
"email": "xxx",
"pass": "yyy",
"contact": [
{
"id": 111,
"name": "AAA"
}
],
"lname": "YYY",
"name": "AAA",
"group": [
{
"name": "AAA",
"lname": "YYY",
}
],
Run Code Online (Sandbox Code Playgroud)
我需要在所有位置查找键“名称”并将其值替换为“XXX”。哪个 jq 命令可以做到这一点?
Mic*_*mer 13
jq 的赋值操作可以一次在尽可能多的位置上执行更新,并且是为这种情况而设计的。您可以使用
jq '(.. | .name?) |= "XXXX"'
Run Code Online (Sandbox Code Playgroud)
在任何地方找到每个名为“name”的字段,并将每个字段中的值一次性替换为“XXXX”,并输出结果对象。
它使用递归下降运营商..
找到树中的每个单独的值,然后从他们每个人翻出了“名称”字段中有.name
,抑制非匹配值的任何错误用?
,然后在一次更新对象在所有这些地方使用更新赋值运算符|=
使用“XXXX” ,并输出新对象。
无论文件结构如何,这都将起作用,并在任何地方更新每个名称字段。
或者,如果文件始终具有此结构,并且您想要更改的是那些特定的“名称”字段,而不仅仅是任何旧名称,您也可以将它们列出并作为一个组分配给它们:
jq '(.name, .contact[].name, .group[].name) |= "XXXX"'
Run Code Online (Sandbox Code Playgroud)
这对
一口气完成。如果文件中可能有其他您不想更改的不相关名称字段,这将特别有用。它只找到在那里命名的三组位置并同时更新它们。
如果值只是像这里这样的文字,那么简单的赋值也可以=
工作并为您节省一个字符:(..|.name?)="XXXX"
- 如果您的值是基于整个顶级对象计算的,您也需要这个。相反,如果您想根据旧名称计算新名称,则需要使用|=
. 如果我不确定要使用什么,|=
通常在极端情况下会有更好的行为。
如果您有多个替换要做,您可以将它们组合在一起:
jq '(..|.name?) = "XXXX" | (..|.lname?) = "1234"'
Run Code Online (Sandbox Code Playgroud)
将在任何地方更新“name”和“lname”字段,并输出整个更新的对象一次。
其他一些可能有效的方法:
您也可以非常明确地说明您选择的内容
(..|objects|select(has("name"))).name |= "XXXX"`
Run Code Online (Sandbox Code Playgroud)
它查找所有内容,然后是对象,然后是具有“名称”的对象,然后是这些对象上的名称字段,并执行与以前相同的更新。
如果你运行的JQ(不太可能)的开发版本,那么该walk
功能还可以做的工作:walk(.name?="XXXX")
。所有其他版本都适用于最新发布的版本 1.5。
另一种多更新可能是
jq '(..|select(has("name"))?) += {name: "XXXX", lname: "1234"}'
Run Code Online (Sandbox Code Playgroud)
它找到具有名称的所有内容,然后使用算术更新赋值*=
和对象的合并行为+
在每个对象上设置“name”和“lname” 。
oli*_*liv 10
使用jq
基于walk
函数(需要最新版本):
jq 'walk(.name?="XXX")' file
Run Code Online (Sandbox Code Playgroud)
如果您jq
不支持该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(.name?="XXX")
' file
Run Code Online (Sandbox Code Playgroud)
学分:https : //github.com/stedolan/jq/issues/963
归档时间: |
|
查看次数: |
25960 次 |
最近记录: |