一行上正好有两个大写的单词



我想创建一个正则表达式,它可以替换包含两个以大写字母开头的单词的行,字符"X"。

我目前正在使用这个:

sed -e '/b[A-Z][a-z]*b c X /home/Morgan/desktop/test

问题如下:它只更改包含 1 个或多个由我的test.txt正则表达式描述的单词的行。

我不知道怎么说我只想要一个 X 在正好 2 个以大写开头的单词的行上。任一单词都可以出现在行中的任何位置。

我的测试.txt包含:

Bonjour

oui oui Bonjour -> 这必须替换为 X

Bonjour Bonjour Bonjour ->这不能

Bonjour Oui bonjour oui -> 这必须替换为 X

您似乎试图使用 Perl/PCRE 字边界b但典型的sed实现不理解这种正则表达式方言。 无论如何,通过您的问题描述,您正在寻找行的开头和结尾;这是一个非常基本的正则表达式锚点,已经在原始grep中引入:^匹配行首,$匹配行尾。

如果没有锚点,正则表达式将匹配行中的任何位置。要说"只有两个",你真的必须检查整条线,并确保没有三个或更多你要找的东西。

"找到一行正好有两个以大写开头的单词"需要稍微改写或按摩一下,然后才能尝试编写正则表达式。 如果我们暂时地将w定义为"不以大写开头的单词",W定义为以大写开头的单词,则需要^w*Ww*Ww*$- 正好是两个大写单词,以及零个或多个非大写单词在它们之前,之间或之后的任何位置。

以大写开头的单词是[A-Z][a-z]*(这要求所有后续字符都是小写的),一个不以大写开头的单词是[a-z][a-z]*的(如果您的sed支持该正则表达式变体,则[a-z]+)。

由于单词之间需要空格,因此需要将可选的单词表达式括起来,以便您可以说"整个序列中的零个或多个"。通常,sed正则表达式也需要将括号分组反斜杠,尽管这在版本之间有所不同。

所以,试试这个:

sed 's/^([a-z][a-z]* )*[A-Z][a-z]*( [a-z][a-z]*)* [A-Z][a-z]*( [a-z][a-z]*)*$/X/' file

如果你确实有GNUsed,这可以简化一点:

sed -r 's/^([a-z]+ )*[A-Z][a-z]*( [a-z]+)* [A-Z][a-z]*( [a-z]+)*$/X/' file

这个"词"的定义可能还不够;也许你可以改进它以适应你的情况。 特别是,假定间距是规则的(单词之间正好是一个空格;行上没有前导或尾随空格),并且任何文本都不能包含空格以外的字符,字母 a-z 为大写或小写。(重音字符(如 è 和 Á)是否也被视为此范围内的字母,取决于您的区域设置。如果法语区域设置很重要,可以在脚本中设置LC_ALL=fr_FR.utf-8

另请注意sedsubstition 命令如何恰好需要三个分隔符 - 传统上,我们使用斜杠,但您可以使用任何标点字符。表单是s/regex/replacement/flags,其中正则表达式、替换和标志都可以为空,但始终需要s和分隔符。

相关内容

  • 没有找到相关文章

最新更新