当前位置: 首页 > 知识库问答 >
问题:

需要用新值替换json中的标记字段

淳于哲
2023-03-14

我正在尝试编写一个批处理脚本来更改以下两个名为example1的JSON的“tags”键的值。json和示例2。json。

输入示例1。json

{
  "info": {
    "title": "My example swagger 1",
    "version": "1.0"
  },
  "paths": {
    "/v1/resource1": {
        "get": {
            "description": "This is the example1",
            "tags": [
                "example1"
            ],
            "consumes": [
                "*/*"
            ]
        }
    },
    "/v1/resource2": {
        "get": {
            "tags": [
                "example1"
            ],
            "consumes": [
                "*/*"
            ]
        }
    }
  }
}

输入example2.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": [
                "*/*"
            ]
        }
    }
  }
}

预期的输出是两个同名的JSON,但标记值现在已更改。

Example1.json:

输入标记值-example1(即json文件名)

输出标签值-tags1(根据要求)

Example2.json

输入标记值-example2(即json文件名)

输出标签值-tags2(根据要求)

输出示例1。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": [
                "*/*"
            ]
        }
    }
  }
}

输出示例2。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": [
                "*/*"
            ]
       }
    }
  }
}

我在批处理脚本中写了下面的命令,但它不起作用

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%替换它。在第4行中,我将格式化json。上面的代码在循环中运行,因此对于第一个循环,变量的值将是

$ echo %1 
$ example1.json
$ echo %oldtagvalue%
$ example1
$ echo %newtagvalue%
$ tag1

对于第二个循环,值将为

$ echo %1 
$ example2.json
$ echo %oldtagvalue%
$ example2
$ echo %newtagvalue%
$ tag2

但它不起作用。请给出建议。我还尝试使用jq命令实现它,但效果不太好。

共有2个答案

诸修伟
2023-03-14

这应该让你开始:

$ 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)

在这两种情况下,输出如下所示。当然,您也可以在jq程序中以编程方式将“exampleN”更改为“tagN”(例如,使用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": [
          "*/*"
        ]
      }
    }
  }
}
陈夜洛
2023-03-14

因此,如果我理解正确,您希望替换具有文件名的标记,并将其替换为您选择的标记。以下是一种方法:

$ 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
 类似资料:
  • 如果要使用相同的变量但值不同,如何替换下一个更改集的标记值。实例 这个例子只适用于第一次和第二次 设置或运行Liquibase时出错:Liquibase。例外设置例外:液化。例外SetupException:分析/patches/translate\me的第150行第67列时出错。xml:cvc复杂类型。2.4.a: 发现以元素“property”开头的内容无效。“{”之一http://www.l

  • 我们有这样一个json字符串: 我们想使用下面的代码来替换后一个key6的值: 但是由于key6在jsonstring中显示了两次,我们替换了错误的值。上面的json结构只是一个例子,“key6”的json路径在不同的json中是完全不同的。我们无法为这种替换编写确切的jsonpath。我们怎么能只是用java替换没有孩子的“key6”的值?多谢了。

  • 希望有人能提供帮助,我正在使用以下代码在React应用程序的endpoint执行抓取: 并返回错误:

  • 问题内容: 我的apicontroller返回了以下JSON对象: 我要替换为 我已经尝试了下面的代码,但它仅代替的第一次出现。如何替换所有条目? 谢谢, 问题答案: 您需要使替换全局: 这样,它将继续替换null直到到达结尾 正则表达式文档: https://developer.mozilla.org/zh- CN/docs/Web/JavaScript/Reference/Global_Obj

  • 问题内容: 我正在使用jQuery的parseJSON()函数将json字符串插入变量中。问题是,它正在将我的数据变成一个对象,而不是一个二维数组。例如, 问题是,“名称”不应该是 键 (假设这是正确的术语)。相反,它应该是: 我将如何转换呢?还是有一个不同于使用for循环遍历数组索引的方法(但仍然可以像在2d数组中一样,以字符串形式访问键和值)。 编辑:这是一些正在使用的json(请注意,它的使

  • 我正在寻找一个注释,我可以用它来替换字符串值为空值Java 有一些@Json注释可以在序列化JSON对象到POJO时进行自定义, 我想这样做: