Bash: 使用 sed 替换代码块,处理缩进

Bash: using sed to replace block of code, treating indents

有一个文件,代码如下:

{
    "name": {
    "port": 4466,
    "host": "localhost",
    "appPort": 3555,
    "abc": {
        "defg": {
            "host": "localhost",
            "port": 5500,
            "userName": "test",
            "password": "test"
        }
    },


    "name2": {
    "port": 4321,
    "host": "localhost",
    "appPort": 1234,
    "abc": {
        "defg": {
            "host": "localhost",
            "port": 5500,
            "userName": "test",
            "password": "test"
        }
    },

等等

我需要使用 sed(或者可能是 awk)替换文件中的以下代码块:

"name": {
    "port": 4466,
    "host": "localhost",
    "appPort": 3555

这是我的,没有成功:

confSearch='"name": {\n        "port": 4466,\n        "host": "localhost",\n        "appPort": 3555'

confReplacement='"name": {\n        "port": 4466,\n        "host": "10.20.30.40",\n        "appPort": 3555'

sed -i "s|$confSearch|$confReplacement|g" "$configFile"

然后我尝试了以下(从 "name" 搜索到“3555”然后替换它):

sed -i "/name.*/ {N; s/name.*3555\./$confReplacement/g}" "$configFile"

我没有收到任何错误,只是找不到搜索文本。我想,那是因为缩进。如何正确对待压痕?或者我应该更喜欢别的东西?只考虑bash,不考虑perl.

非常感谢您的帮助。

看来你只是想更换主机,是吗?使用

之类的东西

sed -i 's/"host":.*$/"host": "10.20.30.40"\n/'.

我建议不要使用 sed 来完成这项任务; JSON 不是基于行的格式,并且 sed 无法处理它,除非您非常确定文件将始终以正确的方式格式化。有一些工具可以正确解析 JSON 并处理它编码的对象,因此缩进或交换行或在同一行上有多个节点不会打扰它们。

在这种特殊情况下,我建议 jq:

jq 'if .name.port == 4466 and .name.appPort == 3555 and .name.host == "localhost" then .name.host="10.20.30.40" else . end' "$configFile"
sed -i '/"port": 4466,/,/"host": "localhost",/ s/localhost/110.20.30.40/' "$configFile"

假设只有 1 台主机的端口为 4466