正则表达式在 Shell 中查找和替换多行

标签 regex shell sed

我的问题与 shell script: search and replace over multiple lines 类似除了一个小异常(exception)。

在链接的问题中,用户想要这样做:

source:
[stuff before]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [stuff here, possibly multiple lines.
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]    

target:
[stuff before]
[new content]
[stuff after]

我的问题是类似的,我想这样做:
source:
[stuff before]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [this]
<!--WIERD_SPECIAL_COMMENT_END-->
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [not this]
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]    

target:
[stuff before]
[new content]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [not this]
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]

在适当的多行正则表达式中,这很容易做到:
/<!--WIERD_SPECIAL_COMMENT_BEGIN-->.*[this].*<!--WIERD_SPECIAL_COMMENT_END-->/m

但是链接问题中建议的答案使用正则表达式作为不允许检查两个外围边界之间的线的范围。

有什么方法可以将一个范围内的所有行添加到模式缓冲区中,以便我可以一次对所有行进行正则表达式?例如:
sed '
    #range between comment beginning and comment end
    /<!--WIERD_SPECIAL_COMMENT_BEGIN-->/,/<!--WIERD_SPECIAL_COMMENT_END-->/
    #Do something to add the lines in this range to pattern buffer
    /.*[this].*/d
    #Delete all the lines if [this] is in the pattern buffer
' <in.txt >out.txt

最佳答案

使用 Perl,它相对简单。

perl -0777pe 's/<!--BEGIN-->\n(?:(?!<!--END-->\n).)*?\[this\].*?\n<!--END-->\n/[new content]\n/s' in.txt

Perl 提供的好处是 (a) -0777 “slurp 模式”,它一次性拉入整个输入文件,而不是 sed 的一次一行处理; (b) /s 正则表达式标志,允许点匹配换行符; (c) 吝啬的重复运算符 *? 和 friend ,导致重复匹配尽可能少而不是尽可能多;最后 (d) 否定前瞻 (?!...),它允许您在否定前瞻表达式匹配的地方禁止匹配。 (没有这个,如果在“stuff before”文本中存在“false”起始分隔符,即使是吝啬的匹配也会匹配结束分隔符。)……当然,(e)一种通用编程语言,其中 sed 是只适用于比较简单的文本处理任务。

(我使用了更简单的开头和结尾分隔符。我希望“wierd”是故意拼错的。)

关于正则表达式在 Shell 中查找和替换多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11689868/

相关文章:

bash - 使用 ffmpeg 转换文件时跟踪日志文件并处理每一行丢失的数据

bash - sed- 删除不包含模式的行

regex - awk 跳过空行

python - 如何检查属于可变大小行 block 的多行的多个条件并返回主行

java通过正则表达式提取地址项

regex - nifi getFile 没有选择文件正则表达式不起作用

JavaScript 检查回文(包括空格和标点符号)

javascript - 正则表达式从YouTube获取get_video_info响应的一部分

bash - 如果存在 `set -e` 指令,为什么 ((0)) 会导致 Bash 脚本退出?

linux - 如何从具有多天数据的日志文件中检索一天数据