6

I have a large dictionary file with 300,000+ words in it and I'm trying to find all words with the vowels aeiou in that order and have only exactly 5 vowels. My current attempt does not seem to be working and for the life of me I don't understand why.

less mywords | grep -iE [^aeiou]*a[^aeiou]*e[^aeiou]*i[^aeiou]*o[^aeiou]*u[^aeiou]*

I think it get's all the words I'm looking for but there are a few words that pop up which I can not get rid of.

abstemiousnesses
ultraserious

There are a few other but they are in the same vein. Curiously, even if I add something like [^u]* to the front ultraserious keeping popping back up! Any solution would be fine however I would like it restricted to grep as we've been told it can be done using only grep.

3
  • Is something like adventitious valid?
    – cuonglm
    Aug 8, 2014 at 7:15
  • No, the vowels have to appear in order and with no other vowels in between. I'll specify that, thanks.
    – Achaldo
    Aug 8, 2014 at 7:16
  • in french y is also a vowel
    – Kiwy
    Aug 8, 2014 at 13:13

1 Answer 1

13

You're not anchoring the expression. It can match in the middle, so any vowels "outside" your match are allowed.

Add a ^ and $ to prevent that.

$ echo abstemiousnesses | grep -iE '[^aeiou]*a[^aeiou]*e[^aeiou]*i[^aeiou]*o[^aeiou]*u[^aeiou]*'
abstemiousnesses
$ echo abstemiousnesses | grep -iE '^[^aeiou]*a[^aeiou]*e[^aeiou]*i[^aeiou]*o[^aeiou]*u[^aeiou]*$'
8
  • Oh wow thank you, I can't believe I spent so much time on the problem and it was that!
    – Achaldo
    Aug 8, 2014 at 7:18
  • See also the -x option. Aug 8, 2014 at 9:39
  • 1
    @Achaldo you could also simplify the syntax a bit by saving the character class as a variable: p='[^aeiou]'; grep -i "^$p*a$p*e$p*i$p*o$p*u$p*$" mywords. Oh, and there is absolutely no reason to use less (or cat which would have been the natural choice), grep can take a file as an argument.
    – terdon
    Aug 8, 2014 at 13:34
  • Following up on the second part of @terdon's comment: the traditional way of running a grep would be grep (option(s)) (pattern(s)) (input_file(s)). If you prefer to see the input up front, and it's a single file, you can say < mywords grep (option(s)) (pattern(s)), which makes the input easy to see while avoiding the "useless use of cat". Aug 8, 2014 at 15:09
  • @Scott why? Why not just grep -foo pattern file? Why add an extra character?
    – terdon
    Aug 8, 2014 at 15:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .