首页 > 解决方案 > 在 bash 脚本中使用 sed 替换多行模式

问题描述

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

如果可以搜索以下内容并将其替换为上述内容,则问题将得到解决。

遇到时的模式是这样的:

        },

      ]
    }
  }
}


{
  "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*"
            }
}
      ]
    }
  }
}

标签: jsonregexbashawksed

解决方案


$ 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*"
            }
}
      ]
    }
  }
}

推荐阅读