将egrep regexps与awk合并?

时间:2014-09-29 02:10:30

标签: regex bash awk grep

我一直试图了解awk如何使用egrep正则表达式。 我有以下示例:

John,Milanos    
Anne,Silverwood    
Tina,Fastman    
Adrian,Thomassonn

我希望使用egrep regexp来处理第二列(本场景中的姓氏),同时打印整行输出。

我最接近的答案是使用?

$ awk -F ',' '{print $2}' | egrep '([a-z])\1.*([a-z])\2'
Thomassonn

然后我会选择#34; Thomassonn"并且egrep回到我最初的全名列表中以获得完整记录。但是,一旦我使用其他过滤器,我就遇到了大量的错误和误报。

期望的结果:

Adrian,Thommasson

2 个答案:

答案 0 :(得分:1)

awk不支持正则表达式中的反向引用。但是,egrep足以实现您期望的结果:

$ egrep ',.*([a-z])\1.*([a-z])\2' file
Adrian,Thomassonn

变体形式

如果有三列或更多列,并且您只想搜索第二列:

egrep '^[^,]*,[^,]*([a-z])\1[^,]*([a-z])\2' file

如果要搜索第三列:

egrep '^[^,]*,[^,]*,[^,]*([a-z])\1[^,]*([a-z])\2' file

如果要搜索任意数量的列中的第一列:

egrep '^[^,]*([a-z])\1[^,]*([a-z])\2' file

答案 1 :(得分:0)

awk不支持反向引用,这是实现您想要的一种方式:

$ cat tst.awk
BEGIN{ FS="," }
{
    numMatches = 0
    fld = $2
    for (charNr=1; charNr <= length($2); charNr++) {
        char = substr($2,charNr,1)
        if (char ~ /[a-z]/)
            numMatches += gsub(char"{2}"," ",fld)
    }
}
numMatches >= 2
$
$ awk -f tst.awk file
Adrian,Thomassonn

如果您想匹配3个序列或任何其他数量的重复字符,只需将{2}更改为{3}或您喜欢的任何数字。

顺便说一下,为了便于所有区域设置,您应该使用[[:lower:]]代替[a-z],如果这是您的真实含义。