在Bash中查找双字符的正则表达式


10

我正在寻找一个正则表达式,该表达式在命令行(Bash)上查找文本,列表等中所有出现的双字符。

主要问题:有没有一种简单的方法来寻找像序列aallttttt,等其中一个定义的正则表达式查找具有相同性质的n个出现次数?我正在寻找的是在非常基本的水平上实现这一目标。在命令行上。在Linux Shell中。

经过大量研究之后,我得出了以下答案-以及由此产生的问题,因此它们只是给我一个提示,指出可能的解决方案。但:

a)(e)grep和反斜杠问题

  • grep 'a\{2\}' 寻找 aa
  • egrep'a{2}' 寻找 aa

问题:设置反冲的必要性是否确实与我使用的命令绑定?如果是这样,有人可以给我提示在这里使用(e)grep时还要考虑什么吗?

b)我的问题在这里找到了这个答案,尽管它并不是我要找的东西:

grep -E '(.)\1' filename查找具有相同字符的条目出现多次,但不问出现的频率。这接近我要寻找的内容,但我仍然想设置一些重复项。

我可能应该将其分为两个或两个以上的问题,但是我不想在这里充斥这个很棒的网站。

PS:还有一个问题,可能是题外话,但:是ininsideaton the shell。并且是on the command line正确的呢?

Answers:


8

这确实是两个问题,应该分开。但是,由于答案相对简单,因此将其放在此处。这些答案grep专门针对GNU 。

a)egrep与相同grep -E。两者都表示应使用“扩展正则表达式”代替grep默认的正则表达式。 grep对于普通的正则表达式需要反斜杠。

man页面:

基本与扩展正则表达式

在基本正则表达式中,元字符+{| 失去其特殊含义;而是使用反斜杠版本\?\ +\ {\ | \(\)

看到 man有关历史惯例和可移植性的更多详细信息,页面。

b)使用egrep '(.)\1{N}'并替换N为您希望替换的字符数减去一个字符(因为点与第一个字符匹配)。因此,如果您想匹配一个重复四次的字符,请使用egrep '(.)\1{3}'


阅读手册页时,我必须对您所指的部分确实有误解或误解。当我研究一些正则表达式教程时,并没有暗示会发生这种行为。我认为正则表达式在某种基础上意味着大多数应用程序都使用相同的符号集。同样,我被证明是错误的。谢谢你的帮助!这确实帮助了我。
erch 2013年

阅读“ 总是使用反斜杠从。,+等字符中获取特殊含义 ”,然后发现似乎相反的指令是最基本的命令,这也很令人困惑。
erch 2013年

@ cellar.dweller令人困惑!许多推理都是历史性的。我对扩展形式更加熟悉,因此我习惯于仅egrep在需要正则表达式时才使用(而不是简单的字符串匹配),这样我就不必担心记住两者之间的差异了grep。正则表达式的类型。
2013年

4
请注意,标准ERE不支持反向引用,而标准BRE则支持。所以grep '\(.\)\1\{3\}'是标准的,grep -E '(.)\1{3}'不是。
斯特凡Chazelas

7

这将查找2个或更多相同字符的事件:

grep -E '(.)\1+' file

如果您的awk具有-o选项,则每次匹配时将其打印在新行上。

grep -Eo '(.)\1+' file

要查找完全符合3个匹配项的匹配项:

grep -E '(.)\1{2}' file

或3个或更多:

grep -E '(.)\1{2,}' file

等等..


编辑

实际上,@ stephane_chazelas关于反向引用和-E是正确的。我已经忘记了。我在BSD grep和GNU grep中尝试过它,并且在那里工作,但是在其他一些问题上却没有。您将需要使用以下版本之一。

常规grep版本:

grep '\(.\)\1\{1,\}' file

grep -o '\(.\)\1\{1,\}' file

grep '\(.\)\1\{2\}' file

grep '\(.\)\1\{2,\}' file

-o选项也不是标准的grep BTW(可能是如果您的grep理解-o,它也可以做反向引用)。


注意grep -E '(.)\1{2,}'文件和grep '\(.\)\1\{2\}'文件是错误的,如alexis所示,应忽略。


到目前为止,谢谢您。但是:我是正确的说法,如果没有-E选择,那grep将不会做太多事情?这将说明很多原因,例如为什么我浪费这么多时间寻找错误的地方!
erch 2013年

如果没有-E选项,您可以在这种情况下执行相同的操作,但是您将需要进行更多的转义并且没有+运算符。.我也将发布示例。
审查者

一个小的更正:grep -E '(.)\1{2}'不完全是“完全匹配3个匹配项”。尽管它将完全匹配三个相同的字符,但它们可以嵌入更长的重复字符串中;例如,它将匹配5个符号的字符串AAAAA。(并且,如果有6个或更多的连续符号,则将匹配不止一次)。
亚历克西斯

是的,您是绝对正确的,它无法按预期工作,实际上不可能那样
。。– Scrutinizer

3

首先,感谢大家的支持性意见和建议。事实证明,我已经很接近答案了。

主要问题是关于:

有没有一种简单的方法来查找相同字符的n次出现,例如aatttttt

简短答案

以下[variation of]命令将重复a至少一次且无限次

grep 'a\{1,}

grep -E \(a\)\{1,\}

egrep a{1,}

或者,使用GNU正则表达式 grep a\+


repeatings数设置花括号内,通过模式{min,max}{n}精确重复n多次,{n,}重复至少n次和{n,m}重复至少n,但在大部分m时间。

因此,提出了第二个问题

是否需要对我使用的命令设置反向间隙?

简短回答:是的,反斜杠的使用取决于使用grep还是使用egrep

  • grep:反斜杠激活元字符[使用基本正则表达式]
  • egrep反斜杠取消激活元字符[使用扩展的正则表达式]

因为这是一个简短的答案,所以我想提供给遇到类似问题的人员,因此我添加了我的基本摘要,其中概述了似乎必须了解的内容以及与grep和一起使用egrep




基本,扩展和GNU正则表达式

基本正则表达式

在使用grepedsed命令

基本正则表达式集的功能是:

  • 大多数元字符(例如,? [ . \ )等)通过反斜杠激活。如果没有反斜杠,则将它们作为搜索词的一部分。
  • ^ $ \<并且\>被支持而没有反斜杠
  • 没有速记字符[ \b\s等]

GNU基本正则表达式添加到这些

  • \?重复字符零或一次(c\?match ccc),是另一种选择\{0,1\}
  • \+重复的字符的至少一个时间(c\+比赛cccccccccc等等),并且是一种替代\{1,\}

  • \|支持(例如grep a\|b将寻找ab

grep -E 使命令能够使用整个扩展正则表达式集:


扩展正则表达式[ERE]

在使用egrepawk并且emacs是基本集加上颇有些特点。

  • 通过反斜杠停用元字符
  • 没有回引用
  • 其他:很多神奇的正则表达式通常可以做一个

GNU扩展正则表达式

增加了以下功能

这两个链接会将一个链接指向regular-expressions.info,除了我在这里提供的出色支持之外,它确实给了我很多帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.