在 sed 中用正则表达式替换字符串

在 sed 中用正则表达式替换字符串

我正在尝试使用 sed 用 regexp 替换命令的输出,但无法解决问题。

我在 regex101.com 中测试了正则表达式,它似乎很好地对我想要的东西进行了分组。但我无法理解 sed 如何与正则表达式组模式一起工作。

这是命令输出:

appstream              CentOS Linux 8 - AppStream
baseos                 CentOS Linux 8 - BaseOS
epel                   Extra Packages for Enterprise Linux 8 - x86_64
epel-modular           Extra Packages for Enterprise Linux Modular 8 - x86_64
extras                 CentOS Linux 8 - Extras

这是我想要解析的内容:

CentOS Linux 8 - AppStream
CentOS Linux 8 - BaseOS
Extra Packages for Enterprise Linux 8 - x86_64
Extra Packages for Enterprise Linux Modular 8 - x86_64
CentOS Linux 8 - Extras

我想到的 sed 正则表达式是这样的:

sed -E 's/"(^.*?\s)([A-Z|a-x].*)"/\2/g'

有人可以帮我找到问题吗?

谢谢!

答案1

有很多问题:

  1. 在单引号内,双引号是文字 - 因为您的命令输出不包含",所以它永远不会匹配

  2. 如果你的命令输出做过有前导引号,那么行锚^永远无法匹配这样的人物

  3. ?您可能在支持 Perl非贪婪修饰符的引擎中测试了您的正则表达式- 在 sed 中,?它要么是文字(BRE),要么是简单的量词(ERE,如这里的标志-E),它将导致.*贪婪匹配 0 或 1 次

  4. \s只匹配一个单身的空白字符;也就像.*?它是严格的 Perl 扩展(尽管最新版本的 GNU sed 支持它) - 为了可移植性,您可能需要更改为[[:blank:]]

  5. |inside[...]并不代表交替(但这不会阻止表达式匹配,但它也会匹配一个|字符)

假设你的 sed 实现支持\s及其补充\S可能是您想要的东西

sed -E 's/^(\S+\s+)([A-Za-z].*)/\2/'

虽然你可以更简单地做

sed -E 's/\S+\s+(.*)/\1/'

甚至只是

sed -E 's/\S+\s+//'

匹配一系列非空格后跟一系列空格,并将其删除。如果你的 sed 这样做不是提供\s和 \S` 那么你可以对 POSIX 字符类执行相同的操作

sed -E 's/[^[:blank:]]+[[:blank:]]+//'

或者,如果您仅限于完整的 POSIX sed(+无论模式如何,其中都不是量词)

sed 's/[^[:blank:]]\{1,\}[[:blank:]]\{1,\}//'

也可以看看为什么我的正则表达式在 X 中有效但在 Y 中无效?

答案2

在非空白字符后查找一系列空格,并将其更改为换行符(因为换行符肯定不会出现)。然后拿走换行符之前的所有内容。您刚刚删除了第一个字段。

sed -e 's/\S\s+/\n/;s/.*\n//' file

相关内容