所以,我花了很长时间,但我终于学会了思考就正则表达式而言,得益于在kwrite
.
但我仍然不知道如何将这些知识转化为grep
.当我知道我在用它做什么时,我喜欢我的grep
,但手册总是让我头疼。
我想匹配类似以下几行的内容:
换行后为大写字母。 CAPI TALSFOLL 欠 一条新线。
即以两个或多个大写字母开头的行。但我不知道怎么办。
在 中kwrite
,我将使用以下方式匹配这些行:
\n[A-Z][A-Z]+
但是grep
……嗯。我有一种感觉,就像这样:
me@ROOROO:~/$ grep "^[A-Z]something" filename
但
me@ROOROO:~/$ grep "^[A-Z][A-Z]+" filename
不起作用(返回一个空文件)。谷歌搜索“grep 匹配一次或多次出现”一词让我相信
me@ROOROO:~/$ grep "^[A-Z][A-Z]*" filename
是正确的语法。但是,唉,这并不能解决问题。
答案1
您在第一个示例中使用了正确的语法;问题是+
只有在使用“扩展”正则表达式时才被认为是特殊的。从 GNU 实现的手册页中grep
:
基本正则表达式与扩展正则表达式
在基本正则表达式中,元字符 ?、+、{、|、( 和 ) 失去了它们的特殊含义;而是使用反斜杠版本 \?、\+、\{、\|、\( 和 \)。
(\?
、\+
、 和\|
是非标准 GNU 扩展)。
所以,你要么需要转义+
(假设是 GNUgrep
或兼容的):
$ grep "^[A-Z][A-Z]\+" filename
\{1,\}
使用GNU 的标准等效项\+
:
$ grep '^[A-Z][A-Z]\{1,\}' filename
甚至在这里:
$ grep '^[A-Z]\{2,\}' filename
grep
或者通过传递标志-E
或运行来打开扩展正则表达式egrep
(egrep
是在 70 年代末引入这些扩展正则表达式的命令):
$ grep -E "^[A-Z][A-Z]+" filename
$ egrep "^[A-Z][A-Z]+" filename
无论如何,所有这些在功能上等同于:
$ grep '^[A-Z][A-Z]' filename
所以你甚至不需要+
操作员。
在你的另一个例子中你尝试过:
$ grep "^[A-Z][A-Z]*" filename
*
适用于基本正则表达式,但它匹配 0 次或多次,而不是 1 次或多次。解决方案在您的答案之所以有效,是因为它说“匹配一个大写字母,然后匹配另一个大写字母,然后匹配 0 个或多个大写字母”。问题中的方法说“匹配一个大写字母,然后匹配1个或多个大写字母”,这是相同的。您还可以用来{min,max}
指定您想要的确切数量,如果您省略max
它则允许任何数量(这也需要扩展正则表达式):
$ egrep "^[A-Z]{2,}"
(作为历史记录,最初egrep
不支持(例如,{min,max}
在 Solaris 11 中仍然不支持)。支持是在添加之前添加的(在这种情况下确实破坏了向后兼容性))。/bin/egrep
\{min,max\}
grep
{min,max}
egrep
egrep
答案2
您只需要添加一个额外的[AZ]。所以就是
me@ROOROO:~/$ grep "^[A-Z][A-Z][A-Z]*" filename
答案3
看起来您需要来自 的正则表达式支持perl
。形式man grep
:
-P, --perl-regexp
Interpret PATTERN as a Perl regular expression. This is highly experimental
and grep -P may warn of unimplemented features.
所以grep -P "^[A-Z][A-Z]+"
可能会更有帮助。