正则表达式和 sed 在多行块中查找字符串块,直到它以 space 结尾

regexp and sed find block of string in multiline block untill it end with space

我尝试捕获那些字符串块并使用正则表达式和 sed 对它们进行评论。 每个块用 space

分隔
some text here 
some text here 

AppServer1:
  name: ${AppServer1.name}
  ip: ${AppServer1.ip}
   
some text here 
some text here 

AppServer2:
  name: ${AppServer1.name}
  ip: ${AppServer1.ip}

some text here 
some text here 
   

我尝试使用这个正则表达式:

sed E '/./{H;1h;$!d} ; x ; s/[^$AppServer1](AppServer1)/#/gi'

但结果是:

 #AppServer1:
      name: $#{AppServer1.name}
      ip: $#{AppServer1.ip}

我在这里缺少什么来评论完整的字符串:

#AppServer1:
#      name: ${AppServer1.name}
#      ip: ${AppServer1.ip}

使用gnu-sed,你可以这样做:

sed '/^AppServer1/I{:a; /^[[:blank:]]*$/!{s/.*/#&/; n; ba;} }' file

some text here
some text here

#AppServer1:
#  name: ${AppServer1.name}
#  ip: ${AppServer1.ip}

some text here
some text here

AppServer2:
  name: ${AppServer1.name}
  ip: ${AppServer1.ip}

some text here
some text here

详情:

  • /^AppServer1/I:搜索 AppServer1 不区分大小写
  • {: 块开始
    • :a: 制作标签a
    • /^[[:blank:]]*$/!如果一行不是空行
    • {s/.*/#&/; n; ba;}:在每行前添加 #,读取下一行并转到标签 a
  • }: 区块结束

使用 awk 你可以这样做:

awk '/^AppServer1/ {b=1} b && !NF {b=0} b {[=11=] = "#" [=11=]} 1' file

some text here
some text here

#AppServer1:
#  name: ${AppServer1.name}
#  ip: ${AppServer1.ip}

some text here
some text here

AppServer2:
  name: ${AppServer1.name}
  ip: ${AppServer1.ip}

some text here
some text here

一个更简单的 sed 解决方案可能是这样的,如果您也同意最后的空行也被注释的话:

sed '/^AppServer1:/,/^[[:space:]]*$/s/^/# /' lines.txt 
some text here
some text here

# AppServer1:
#   name: ${AppServer1.name}
#   ip: ${AppServer1.ip}
# 
some text here
some text here

AppServer2:
  name: ${AppServer1.name}
  ip: ${AppServer1.ip}

some text here
some text here

它使用 sed 范围模式,用逗号 (,) 表示。范围的开始是 /^AppServer1:/,即任何以 AppServer1: 开始 (^) 的行。范围的末尾是空行或仅包含空白字符的行:/^[[:space:]]*$/,其中 ^:行首; [[:space:]]*:零个或多个 (*) 个空白字符 ([[:space:]]); $: 行尾。

接下来是 [s] 替换命令 — s/^/# / — 它在匹配范围内的所有行上用序列 # 替换行 ^ 的开头(包括结尾).

如果你想要不区分大小写的匹配,你需要 GNU sed。在这种情况下,您可以将 I 标志添加到范围起始模式。不过,此标志在 macOS sed 上不可用。

假设输入中看起来空的行确实是空的,您可以在每个 Unix 机器上使用任何 shell 中的任何 awk 来做到这一点:

$ awk -v RS= -v ORS='\n\n' '/^AppServer1:/{gsub(/^|\n/,"&#")} 1' file
some text here
some text here

#AppServer1:
#  name: ${AppServer1.name}
#  ip: ${AppServer1.ip}

some text here
some text here

AppServer2:
  name: ${AppServer1.name}
  ip: ${AppServer1.ip}

some text here
some text here