首页 > 解决方案 > sed 将不匹配下一行

问题描述

我有以下名为 VERSIONSFILE 的文件:

[GUI]
Version="3.02.104"

[NOTGUI]
Version="1.05.24"

[ALSONOTGUI]
Version="3.01.230"

我正在寻找通过 Windows .bat 文件替换版本号。目前,我正在使用 GNU sed 替换文件。我正在运行的 sed 命令如下:

sed -r -i.bak -e "s/[GUI][\r\n]Version.*$/[GUI]\nVersion=\"3.02.108\"/gm" "VERSIONSFILE" "VERSIONSFILE"

据我所知,它应该匹配并将新版本号输出为 3.02.108。我在下面检查了我的正则表达式,它也正确输出了我的预期结果。

https://regex101.com/r/GaSxKY/6

[GUI] 第一段找到 [GUI] 字符串。

[\r\n] 匹配任何换行符,在这种情况下,我期待 \n,但认为添加两者都不会受到伤害。

Version.*$ 匹配整个版本行,以确保它选择所有内容,仅此而已。

我也尝试过使用 powershell replace,并且遇到了完全相同的问题,它似乎无法在下一行出现。这两种方法我都可以替换 1 行,但不能一次替换 2 行。

标签: regexlinuxsed

解决方案


默认情况下,sed以每行为基础工作。有一个特殊的结构允许将整个文件“slurping”成一个字符串,类似于在 powershell 中,但在这里使用特殊语言Get-Content -Raw是有意义的。sed

利用

sed -r -i.bak '/^\[GUI]$/{N;s/\nVersion.*/\nVersion="3.02.108"/}' file
# Or
sed -r -i.bak '/^\[GUI]$/{n;s/Version.*/Version="3.02.108"/}' file

这里,

  • /^\[GUI]$/- 找到一条等于[GUI]

接着

  • N;- 读取下一行,将行追加\n到模式空间
  • s/\nVersion.*/\nVersion="3.02.108"/ - 替换换行符(由N命令添加)和以下以换行符开头Version的行和Version="3.02.108"

或者,

  • n;- 打印当前模式空间,清空当前模式空间,并读入下一行输入(因此,与上面的不同之处在于,第一个“上下文”行从替换命令将处理的字符串中删除,并且有将不需要匹配\n不适用于所有sed版本)
  • s/Version.*/Version="3.02.108"/- 用文本 替换从字符串开始Version到字符串结尾的子字符串。Version="3.02.108"

查看在线演示


推荐阅读