我正在寻找一个正则表达式,它可以在命令行(Bash)上查找文本、列表等中所有出现的双字符。
主要问题:是否有一种简单的方法来查找诸如aa
、ll
、ttttt
等序列,其中定义一个正则表达式来查找相同字符的 n 次出现?我所寻求的是在非常非常基础的层面上实现这一目标。在命令行上。在 Linux Shell 中。
经过相当多的研究后,我得出了以下答案 - 以及由此产生的问题,因此它们只是给了我解决方案可能在哪里的提示。但:
a) (e)grep 和反斜杠问题
grep 'a\{2\}'
寻找aa
egrep'a{2}'
寻找aa
问题:设置间隙的必要性真的与我使用的命令有关吗?如果是这样,有人可以告诉我在这里使用 (e)grep 时还需要考虑什么吗?
b) 我发现这个答案在这里对于我的问题,尽管这并不完全是我想要的:
grep -E '(.)\1' filename
查找具有多次出现的相同字符的条目,但是不问多久一次。这与我正在寻找的很接近,但我仍然想设置一些重复。
我可能应该将其分成两个或更多问题,但我不想在这里淹没这个很棒的网站。
PS:另一个问题,可能偏离主题,但是:是in
,,inside
还是。并且是正确的吗?at
on the shell
on 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相同字符的出现,例如
aa
,tttttt
简短回答:
以下命令的[变体]将重复a
至少一次和无限次
grep 'a\{1,}
grep -E \(a\)\{1,\}
egrep a{1,}
或者,使用可用的 GNU 正则表达式
grep a\+
重复次数设置在大括号内,通过模式{min,max}
→{n}
重复精确n
次数、{n,}
重复至少n
次数和{n,m}
重复至少n
但最多m
次数。
因此,提出了次要问题:
设置间隙的必要性是否与我使用的命令有关?
简短回答: 是的,反斜杠的使用取决于是否使用grep
或egrep
grep
:反斜杠激活元字符[使用基本正则表达式]egrep
反斜杠德-激活元字符[使用扩展正则表达式]
grep
由于这是简短的答案,我想为那些遇到类似问题的人提供帮助,我添加了我的基本摘要,内容是人们在使用和 时似乎必须注意的事项egrep
。
基本、扩展和 GNU 正则表达式
基本正则表达式
用于grep
,ed
和sed
命令
基本正则表达式集功能有:
- 大多数元字符(例如
? [ . \ )
等)是通过反斜杠激活的。如果没有反斜杠,它们将被视为搜索词(的一部分)。 ^ $ \<
并且\>
支持不带反斜杠- 没有速记字符 [
\b
、\s
等]
GNU基本正则表达式添加到这些
\?
重复字符零次或一次(c\?
匹配c
和cc
)并且是\{0,1\}
\+
重复一个字符至少一次(c\+
匹配cc
等cccccccc
)并且是替代\{1,\}
\|
支持(例如grep a\|b
将寻找a
或b
grep -E
使命令能够使用整套扩展正则表达式:
扩展正则表达式 [ERE]
用于egrep
、awk
和emacs
是基本集加上相当多的一些功能。
- 元字符通过反斜杠停用
- 没有反向引用
- 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