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

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

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

主要问题:是否有一种简单的方法来查找诸如aallttttt等序列,其中定义一个正则表达式来查找相同字符的 n 次出现?我所寻求的是在非常非常基础的层面上实现这一目标。在命令行上。在 Linux Shell 中。

经过相当多的研究后,我得出了以下答案 - 以及由此产生的问题,因此它们只是给了我解决方案可能在哪里的提示。但:

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

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

问题:设置间隙的必要性真的与我使用的命令有关吗?如果是这样,有人可以告诉我在这里使用 (e)grep 时还需要考虑什么吗?

b) 我发现这个答案在这里对于我的问题,尽管这并不完全是我想要的:

grep -E '(.)\1' filename查找具有多次出现的相同字符的条目,但是不问多久一次。这与我正在寻找的很接近,但我仍然想设置一些重复。

我可能应该将其分成两个或更多问题,但我不想在这里淹没这个很棒的网站。

PS:另一个问题,可能偏离主题,但是:是in,,inside还是。并且是正确的吗?aton the shellon the command line

答案1

这确实是两个问题,应该分开回答。但由于答案比较简单,我就放在这里。这些答案专门针对 GNU grep

a)egrep与 相同grep -E。两者都表明应该使用“扩展正则表达式”而不是grep默认的正则表达式。 grep普通正则表达式需要反斜杠。

man页面:

基本正则表达式与扩展正则表达式

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

man有关历史约定和可移植性的更多详细信息,请参阅该页面。

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

答案2

这将查找同一字符出现 2 次或多次:

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

如果你的 awk 有 -o 选项,这会将每个匹配打印在新行上。

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

要查找恰好有 3 个匹配项的匹配项:

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

或 3 个或更多:

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

ETC..


编辑

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

常规 grep 版本:

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

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

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

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

-o选项也不是标准 grep 顺便说一句(可能如果你的 grep 理解 -o 它也可以进行反向引用)。


笔记grep -E '(.)\1{2,}'文件和grep '\(.\)\1\{2\}'文件是错误的,如亚历克西斯指示,应被忽略。

答案3

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

主要问题是关于:

有没有简单的方法可以查找n相同字符的出现,例如aatttttt

简短回答:

以下命令的[变体]将重复a至少一次和无限次

grep 'a\{1,}

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

egrep a{1,}

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


重复次数设置在大括号内,通过模式{min,max}{n}重复精确n次数、{n,}重复至少n次数和{n,m}重复至少n但最多m次数。

因此,提出了次要问题:

设置间隙的必要性是否与我使用的命令有关?

简短回答: 是的,反斜杠的使用取决于是否使用grepegrep

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

grep由于这是简短的答案,我想为那些遇到类似问题的人提供帮助,我添加了我的基本摘要,内容是人们在使用和 时似乎必须注意的事项egrep




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

基本正则表达式

用于grep,edsed命令

基本正则表达式集功能有:

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

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

  • \?重复字符零次或一次(c\?匹配ccc)并且是\{0,1\}
  • \+重复一个字符至少一次(c\+匹配cccccccccc)并且是替代\{1,\}

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

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


扩展正则表达式 [ERE]

用于egrepawkemacs是基本集加上相当多的一些功能。

  • 元字符通过反斜杠停用
  • 没有反向引用
  • else:许多神奇的正则表达式通常可以做的事情

GNU扩展正则表达式

添加以下功能

这两个链接将定向到regular-expressions.info,除了我在这里得到的大力支持之外,它确实对我帮助很大。

答案4

将提出我的解决方案,因为其他人可能会发现它很有用。

只需匹配<character>+(character).

z='foo_bar__yo___hak____woot_tut'
echo ${z//_+(_)}
foo_baryohakwoot_tut

您还可以更进一步,替换混合子字符串,如下所示:

z='foo_bar__yo___hak__-_woot_tut'
echo ${z//_+([-_])/_}
foo_bar_yo_hak_woot_tut

相关内容