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

时间:2015-01-15 11:55:26

标签: bash sed

有一个文件,代码如下:

{
    "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"

然后我尝试了以下内容(从"名称"到" 3555"然后替换它)搜索:

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

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

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:1)

我建议不要使用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"

答案 1 :(得分:1)

sed -i '/"port": 4466,/,/"host": "localhost",/ s/localhost/110.20.30.40/' "$configFile"

假设只有1个主机端口4466

答案 2 :(得分:0)

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

这样的东西

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