Regex Awk正则表达式匹配问题

Regex Awk正则表达式匹配问题,regex,bash,awk,Regex,Bash,Awk,我在使用带有awk的正则表达式时遇到问题。特别是,我需要在文件中查找以下所有单词: 以“联合国”开始 长度至少为6个字符 以两个元音结尾 (必须同时验证这些条件)。 我用过这个正则表达式 cat file.txt | awk '{ for(k=1; k<=NF; k++) if ($k ~ /^un.{2,}[aeiouAEIOU]{2}$/ ) print $k; }'

我在使用带有awk的正则表达式时遇到问题。特别是,我需要在文件中查找以下所有单词:

  • 以“联合国”开始
  • 长度至少为6个字符
  • 以两个元音结尾
(必须同时验证这些条件)。
我用过这个正则表达式

cat file.txt | awk '{ for(k=1; k<=NF; k++) 
                         if ($k ~ /^un.{2,}[aeiouAEIOU]{2}$/ ) 
                             print $k; }'
file.txt

unaaaiuolaa
unarmadio
奇怪的是,正则表达式匹配了第一个文件中的所有单词,但file.txt中只有“unarmadio”(请注意,“unaaiuolaa”在两个文件中是相同的)


有人能解释一下原因吗

在awk中使用循环是一种非常奇怪的构造;我会的

awk '/^un.{2,}[aeiouAEIOU]{2}$/' < file.txt
awk'/^un.{2,}[aeiouAEIOU]{2}$/'
下面的另一种方法,如果一行中有多个单词,请使用问题中给出的for循环方法(一种处理FS变量给出的行中每个项目的常用方法)。在应用regexp之前检查长度,regexp使用贪婪运算符表示“任意字符”,然后使用两个相同的字符类来确保一个项目以两个元音结尾

{ for(k=1; k<=NF; k++)  {
        if (length($k) > 5) {
            if ($k ~ /^un.*[aeiou][aeiou]$/) {
                print $k;
            }
        }
    }
}
{for(k=1;k5){
如果($k~/^un.[aeiou][aeiou]$/){
打印$k;
}
}
}
}

正如grok12所说,问题在于“unaaiuolaa”结尾的空白处。删除它解决了问题。

我可以获得您的结果的一种方法是将您的调用更改为下面Tom Womack的答案,并在file.txt中“unaaiuolaa”的末尾添加一个额外的空格。我为什么要添加一个额外的空格?(然而,这并没有改变结果)您使用的是什么版本的awk?我使用的是gawk,
{2,}
{2}
表达式只有在使用
--re interval
标志时才有效。可能与您无关,因为您使用的是一个文件(对我来说,这两个输入都不带标志,两个输入都带标志),但我想我会问一下以防万一。虽然这可能很奇怪,但我很确定这是一个有效的语法。此外,您的解决方案一直匹配“unarmadio”,但不匹配“unaaiuolaa”。根据pholser的评论,“unaaaaiuolaa”的末尾可能有空白,因此此正则表达式可能应以}结尾*$/
{ for(k=1; k<=NF; k++)  {
        if (length($k) > 5) {
            if ($k ~ /^un.*[aeiou][aeiou]$/) {
                print $k;
            }
        }
    }
}