【问题标题】:Multiline pattern replacement with sed in bash script在 bash 脚本中使用 sed 替换多行模式
【发布时间】:2021-09-12 05:01:37
【问题描述】:

尝试用两个字符},替换多行

如果可以搜索到下面的内容并用上面的替换,那么问题就解决了。

模式遇到时是这样的:

        },

      ]
    }
  }
}


{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [

这些是我目前尝试过的方法

    #using \ and spaces
combinedDSL=$(echo "$initialDSLs"|sed 's/}\
      ]\
    }\
  }\
}\
\
*\
{\
  "query": {\
    "bool": {\
      "minimum_should_match": 1,\
      "should": [\
/},/' )

echo "$combinedDSL"

#using line breaks \n 

combinedDSL2=$(echo "$initialDSLs|"sed N 's/}\n]\n}\n}\n}\n\n*\n{\n"query": {\n"bool": {\n"minimum_should_match": 1,\n"should": [\n/},/')
echo "$combinedDSL2"

这里是完整的上下文:

{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [
    

        {
          "wildcard": {
            "author_place": "*city*"
          }
        },
        
        {
          "wildcard": {
            "meta.title.results": "*state*"
          }
        },

      ]
    }
  }
}


{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [
    

            {
            "wildcard": {
                "author": "*cat*"
            }
            },
            
            {
            "wildcard": {
                "meta.hashtag.results": "*Monkey*"
            }
}
      ]
    }
  }
}

【问题讨论】:

  • edit 你的问题是在上下文中显示目标行,这些行被你不想匹配的行包围,并在给定输入的情况下添加预期的输出。
  • 这看起来像 JSON,这意味着您需要使用像 jq 这样的 JSON 感知工具来处理它。
  • 我已将上下文添加到问题中。 @埃德莫顿
  • 您提供的“上下文”中没有任何部分与您要替换的字符串匹配。每一行之间有不同数量的空白行,一个逗号在另一个中不存在,并且缺少换行符和不同的缩进。请清理您的示例,以便您要查找的字符串存在于您的示例输入中。
  • 通过大量工作,您可能可以创建一个复杂的正则表达式,为您的特定 JSON 文件完成这项工作。但在我看来,这是该项目的错误工具。最好学习如何使用现有的许多 JSON 工具,并且下次更加灵活。

标签: json regex bash awk sed


【解决方案1】:
$ cat tst.sh
#!/usr/bin/env bash

old='        },

      ]
    }
  }
}


{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [
'

new='
},'

# https://stackoverflow.com/questions/29613304/is-it-possible-to-escape-regex-metacharacters-reliably-with-sed
# explains how in the script below we turn "old" above into a robust
# regexp that's forgiving of white space differences in the target file
# and deactivate the possible backreference in "new".

old="$old" new="$new" awk '
    BEGIN {
        old = ENVIRON["old"]
        new = ENVIRON["new"]

        # Deactivate possible regexp metachars in "old"
        gsub(/[^^\\[:space:]]/,"[&]",old) # deactivate all non-space chars except ^ and \
        gsub(/\^/,"\\^",old)            # deactivate ^
        gsub(/\\/,"\\\\",old)           # deactivate \

        # Make any literal white space present in "old" match all white space
        gsub(/[[:space:]]+/,"[[:space:]]+",old)

        # Deactivate possible backreference metachars in "new"
        gsub(/&/,"\\&",new)             # deactivate &
    }
    {
        # Create a single input record out of the whole input file
        rec = (NR>1 ? rec RS : "") $0
    }
    END {
        gsub(old,new,rec)
        print rec
    }
' "${@:--}"

$ ./tst.sh file
{
  "query": {
    "bool": {
      "minimum_should_match": 1,
      "should": [


        {
          "wildcard": {
            "author_place": "*city*"
          }
        },

        {
          "wildcard": {
            "meta.title.results": "*state*"
          }
},{
            "wildcard": {
                "author": "*cat*"
            }
            },

            {
            "wildcard": {
                "meta.hashtag.results": "*Monkey*"
            }
}
      ]
    }
  }
}

【讨论】:

    猜你喜欢
    • 2020-09-22
    • 2013-07-21
    • 2013-04-30
    • 2022-07-21
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 2017-06-16
    • 2011-08-16
    相关资源
    最近更新 更多