我正在尝试编写一个批处理脚本来更改名为example1.json和example2.json的以下2个jsons的“tags”键的值。
输入example1.json
{
"info": {
"title": "My example swagger 2",
"version": "1.0"
},
"paths": {
"/v1/resource3": {
"get": {
"description": "This is the example2",
"tags": [
"example2"
],
"consumes": [
"*/*"
]
}
},
"/v1/resource4": {
"get": {
"tags": [
"example2"
],
"consumes": [
"*/*"
]
}
}
}
}
输入example2.json
{
"info": {
"title": "My example swagger 1",
"version": "1.0"
},
"paths": {
"/v1/resource1": {
"get": {
"description": "This is the example1",
"tags": [
"tag1"
],
"consumes": [
"*/*"
]
}
},
"/v1/resource2": {
"get": {
"tags": [
"tag1"
],
"consumes": [
"*/*"
]
}
}
}
}
预期输出是两个具有相同名称的jsons,但标签值现在已更改。
Example1.json:
输入标签值 - example1(这是json文件名)
输出标签值 - tags1(根据要求)
Example2.json
输入标签值 - example2(这是json文件名)
输出标签值 - tags2(根据要求)
输出Example1.json
{
"info": {
"title": "My example swagger 2",
"version": "1.0"
},
"paths": {
"/v1/resource3": {
"get": {
"description": "This is the example2",
"tags": [
"tag2"
],
"consumes": [
"*/*"
]
}
},
"/v1/resource4": {
"get": {
"tags": [
"tag2"
],
"consumes": [
"*/*"
]
}
}
}
}
输出Example2.json
sed -i "s/$/ #removenewlines#/" %1
sed -i ":a;N;$!ba;s/\n//g" %1
sed -i "s/\"tags\":\(.*\) \"%oldtagvalue%\"/\"tags\":\1 \"%newtagvalue%\"/g" %1
sed -i "s/ #removenewlines#/\n/g" %1
我在批处理脚本中编写了以下命令,但它无法正常工作
\(.*\)
由于sed不适用于多行,我将换行符更改为#removenewlines#并将所有内容移至单行(第1行和第2行)。在第3行中,我尝试使用通配符%oldtagvalue%
和变量%newtagvalue%
找到关键标记,然后用$ echo %1
$ example1.json
$ echo %oldtagvalue%
$ example1
$ echo %newtagvalue%
$ tag1
替换它。在第4行,我正在格式化json。
上面的代码在循环中运行,因此对于变量的第一个循环值将是
$ echo %1
$ example2.json
$ echo %oldtagvalue%
$ example2
$ echo %newtagvalue%
$ tag2
对于第二个循环值将是
awk
但它不起作用。请指教。我也尝试使用jq命令实现它,但它没有用。
答案 0 :(得分:1)
因此,如果我理解正确,您希望替换具有文件名称的标签,并将其替换为您选择的标签。这是你可以做到的一种方式:
$ jq --arg newtag 'tag1' '(input_filename | sub("\\.json$"; "")) as $oldtag
| .paths[][].tags |= map(if . == $oldtag then $newtag else . end)' example1.json
如果您想替换任意标签而不只是替换与文件名匹配的标签,只需添加另一个参数:
$ jq --arg oldtag 'example1' --arg newtag 'tag1' \
'.paths[][].tags |= map(if . == $oldtag then $newtag else . end)' example1.json
如果您希望能够替换多个不同的标签,您可以创建一个对象,将旧标签映射到新标签并构建它。
$ jq --argjson tagmap '{"example1":"tag1","example2":"tag2"}' \
'.paths[][].tags |= map($tagmap[.] // .)' example1.json
答案 1 :(得分:0)
这应该让你开始:
$ jq --arg tag "tag1" '
.paths |= with_entries(.value.get.tags[] = $tag)' Example1.json
或者稍微不同,你可以使用这个过滤器:
# 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 has("tags") then .tags[] |= $tag else . end)
在这两种情况下,输出如下所示。你当然也可以改变"例如N"到" tagN"以编程方式在jq程序中(例如使用sub/2
),如果这是你想要的。重要的是,只有jq才能完成这项工作。
{
"info": {
"title": "My example swagger 1",
"version": "1.0"
},
"paths": {
"/v1/resource1": {
"get": {
"description": "This is the example1",
"tags": [
"tag1"
],
"consumes": [
"*/*"
]
}
},
"/v1/resource2": {
"get": {
"tags": [
"tag1"
],
"consumes": [
"*/*"
]
}
}
}
}