grep从资本开始,恰好出现三次

问题描述 投票:0回答:4

我需要强调这一点:以资本开头的那条线和相同的资本必须在线上完全出现3次。例如。这是一个很好的路线:

'X^[<*'??X+BXK<:B7#;}V0|<|K!(P|HW}(1O@$JK_}}*.5H"Y&^A)D$QS97R' 

(以X和X开头显示三次)我试过这个,但显然括号之间的反向引用无法正常工作:

 ^\([A-Z]\)[^\1]*\1[^\1]*\1[^\1]* 

为什么这不起作用,我应该怎么做?

regex unix grep
4个回答
0
投票

grep中,您需要使用\(...\)来创建捕获组。对于“以大写字母开头并且同一个字母出现三次”,您可以:

grep '^\([A-Z]\).*\1.*\1'

0
投票

我会用awk

$ cat ip.txt
Xq2X46Xad
asAnAndA
YeYeYeY
CCC
EsE63Eu6u

$ awk '/^[A-Z]/{c=substr($0,1,1); n=split($0,a,c); if(n==4)print}' ip.txt
Xq2X46Xad
CCC
EsE63Eu6u
  • /^[A-Z]/如果行以大写字母开头
  • c=substr($0,1,1)将该字母保存在变量中
  • n=split($0,a,c)使用该字母分割线并保存n中获得的字段数
  • 如果有四个字段,则打印该行

可以缩短为

$ awk '/^[A-Z]/ && split($0,a,substr($0,1,1))==4' ip.txt
$ # or, with GNU awk
$ gawk -v FS= '/^[A-Z]/ && split($0,a,$1)==4' ip.txt

0
投票

[^\1]并不意味着反对引用\1的否定。

你必须使用负向前瞻,hanchor开始和结束,以及-P选项(对于PCRE):

grep -P '^([A-Z])(?:(?!\1).)*\1(?:(?!\1).)*\1(?:(?!\1).)*$'

如果它是首都,这将在第一个字符的每一行中恰好匹配3次


0
投票

使用awk在FS为空时将输入拆分为字符(例如GNU awk):

$ awk -F '' '/^[A-Z]/ && gsub($1,"&")==3' file
X^[<*'??X+BXK<:B7#;}V0|<|K!(P|HW}(1O@$JK_}}*.5H"Y&^A)D$QS97R

在任何UNIX机器上的任何shell中都有任何awk:

$ awk '/^[A-Z]/ && gsub(substr($0,1,1),"&")==3' file
X^[<*'??X+BXK<:B7#;}V0|<|K!(P|HW}(1O@$JK_}}*.5H"Y&^A)D$QS97R

您可能希望将A-Z更改为[:upper:]以便移植到其他语言环境。

© www.soinside.com 2019 - 2024. All rights reserved.