Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
    
Is something like adventitious valid? –  cuonglm Aug 8 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 at 7:16
    
in french y is also a vowel –  Kiwy Aug 8 at 13:13

1 Answer 1

up vote 12 down vote accepted

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]*$'
share|improve this answer
    
Oh wow thank you, I can't believe I spent so much time on the problem and it was that! –  Achaldo Aug 8 at 7:18
    
See also the -x option. –  Stéphane Chazelas Aug 8 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 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". –  Scott Aug 8 at 15:09
    
@Scott why? Why not just grep -foo pattern file? Why add an extra character? –  terdon Aug 8 at 15:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.