Вот попытка Awk, которая собирает все попадания за один проход по входному файлу, а затем печатает каждое ведро.
awk 'BEGIN { split("a:e:i:o:u", vowel, ":")
c = "[b-df-hj-np-tv-z]"
for (v in vowel)
regex = (regex ? regex "|" : "") "^" c "*" vowel[v] c "*(" vowel[v] c "]*)*$" }
$0 ~ regex { for (v in vowel) if ($0 ~ vowel[v]) {
hit[v] = ( hit[v] ? hit[v] ORS : "") $0
next } }
END { for (v in vowel) {
printf "=== %s ===\n", vowel[v]
print hit[v] } }' /usr/share/dict/words
Вы заметите, что оно печатает слова с слоговым y как jolly и цикл. Более сложное регулярное выражение должно исправить это, хотя для действительно сложных случаев (таких как рифма ) нужна более сложная модель английского языкаорфография.
Регулярное выражение неуклюже, потому что Awk не поддерживает обратные ссылки;более ранняя версия этого ответа содержала более простое регулярное выражение, которое работало бы с grep -E
или аналогичным, но затем собирало все совпадения в одном сегменте.
Демо: https://ideone.com/wNrvPu