我想创建一个正则表达式,它可以替换包含两个单词的行,这两个单词以大写字母“X”开头。
我目前正在使用它:
sed -e '/\b[A-Z][a-z]*\b c X /home/Morgan/desktop/test
问题如下:它只更改包含我test.txt
中正则表达式所描述的1个或多个单词的行。
我不知道怎么说我只想要一个只有2个以大写字母开头的行的X.这两个词都可以出现在该行的任何地方。
我的test.txt包含:
Bonjour oui oui Bonjour - >这必须由X
代替Bonjour Bonjour Bonjour - >这一定不能
Bonjour Oui bonjour oui - >这必须由X
代替
答案 0 :(得分:3)
您似乎尝试使用Perl / PCRE字边界\b
,但典型的sed
实现不理解这种正则表达式方言。通过你的问题描述,无论如何,你正在寻找线的起点和终点;这是一个非常基本的正则表达式锚点,已在原始grep
中引入:^
匹配行的开头,$
匹配行尾。
没有锚点,正则表达式将匹配行中的任何位置。要说“只有两个”你真的必须检查整行,并确保没有三个或更多你正在寻找。
“找到一行只包含两个以大写字母开头的单词”需要重新编写或按摩一下才能尝试编写正则表达式。如果我们 - 暂时,在本次讨论中 - 将w
定义为“不以大写字母开头的单词”,将W
定义为表示您需要的单词^w*Ww*Ww*$
两个大写单词,在它们之前,之间或之后的任何位置都有零个或多个非大写单词。
以大写字母开头的单词是[A-Z][a-z]*
(这需要所有后续字符都是小写),而单词不是[a-z][a-z]*
(或[a-z]\+
如果你的{sed
1}}支持正则表达式变体)。
因为单词之间需要空格,所以需要将可选的单词表达式括起来,这样就可以说“整个序列中的零个或多个”。通常,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
如果您确实拥有GNU sed
,可以稍微简化一下:
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
。)
另请注意sed
替换命令如何只需要三个分隔符 - 传统上,我们使用斜杠,但您可以使用任何标点字符。表单为s/regex/replacement/flags
,其中正则表达式,替换符和标志都可以为空,但始终需要s
和分隔符。