我发现了许多类似的问题,但大多数问题连续问元音很容易。我想使用grep查找不连续包含20个元音的单词。
我原本以为grep -Ei [aeiou] {20}会这样做,但似乎只能连续搜索20个元音
答案 0 :(得分:2)
我不认为这是仅需要正则表达式的问题。这是一种编程方法。我们将字段分隔符重新定义为空字符串;每个字符都是一个字段。我们遍历该行;如果字符是元音,我们将增加一个计数器。如果在字符串的末尾计数为20,则将其打印出来:
cat nicks.awk
BEGIN{
FS=""
}
{
c=0;
for( i=1;i<=NF;i=i+1 ){
if ($i ~ /[aeiou]/ ){
c=c+1;
}
};
if(c==20){
print $0
}
}
这就是它的作用……它只打印出一个有20个元音的字符串。
echo "contributorNickSequestionsfoundcontainingvowelsgrcep" | awk -f nicks.awk
echo "contributorNickSeoquestionsfoundcontainingvowelsgrcep" | awk -f nicks.awk
contributorNickSeoquestionsfoundcontainingvowelsgrcep
echo "contributorNickSaeoquestionsfoundcontainingvowelsgrcep" | awk -f nicks.awk
答案 1 :(得分:1)
使用正则表达式搜索由任意数量的辅音分隔的20个元音。
grep -Ei "[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*\
[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*\
[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*\
[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*\
[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*\
[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*\
[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*[aeiou][b-df-hj-np-tv-z]*"
反斜杠只是告知外壳程序表达式在下一行继续。它不是正则表达式本身的一部分。
如果您了解该部分,则可以使用组将其大大缩短。此正则表达式与上述相同,但在括号中使用重复的组。
grep -Ei "([aeiou][b-df-hj-np-tv-z]*){20}"
答案 2 :(得分:0)
如果您真正需要的是在一行中找到20个元音,那就是:
awk '{x=tolower($0)} gsub(/[aeiou]/,"&",x)==20' file
或使用grep:
grep -Ei '^[^aeiou]*([aeiou][^aeiou]*){20}$' file
要查找单词(假设每个单词都用空格分隔),GNU awk包括很多选项:
awk -v RS='\\s+' -v IGNORECASE=1 'gsub(/[aeiou]/,"&")==20' file
或与此任何awk:
awk '{for (i=1;i<=NF;i++) {x=tolower($i); if (gsub(/[aeiou]/,"&",x)==20) print $i} }' file