1

I encountered this question in my test: Make echo output all directories that start with a vowel (a,e,i,o,u,e), end with a number and have at least 3 characters. I thought this would be fairly easy, but soon I ended up confused and evetually failed the test. My first thought was simply:

echo {a,e,i,o,u,e}*{0..9}

Then I tried to use square brackets

echo [a,e,i,o,u,e]*[0..9]

and at the end i tried something like this:

echo $(ls {a,e,i,o,u,e}*{0..9})

which gave me the required output, but with some error directory missing messages, and Im not even sure if it wouldnt be considered cheating as Im using another function to do it.

Could anyone clarify for me, how do I do it and when do I use which brackets? And I would also like to know, how does echo recognize when it should output list of directories instead of my exact words.

  • 2
    you should use echo [aeiou]?*[0-9] – mosvy Oct 21 '18 at 19:33
  • 1
    {a,e} and {0..9} braces will expand even if there are no files matching them, [a,e] and [0..9] are not the proper way to write a glob range (the latter will match 0, . and 9), but [ae] and [0-9], and [ae]*[0-9] will also match filenames of two characters, thence ?* instead of *. – mosvy Oct 21 '18 at 19:42
  • 2
    echo can't differentiate files from directories, so your test can only be completed successfully if there is an implicit understanding that there are only directories that will match your wildcard pattern. – roaima Oct 21 '18 at 19:56
2

To extend mosvy's comment with roaima's clarification, I would suggest:

echo [aeiou]?*[0-9]/

This uses filename expansion (globbing) features to pick up your requirements for:

  • a directory or symlink to directory (the trailing slash /)
  • that starts with an English lower case vowel ([aeiou])
  • contains at least one additional character (?)
  • and has at least three characters (* will match zero or more characters, adding to the two we already matched and the one we're matching at the end, below)
  • ends with a decimal digit ([0-9])

Your shell expands any matching directory names and passes those to echo, which simply echoes them out.

Note, though, that with some shells including bash, if there are no directories matching the requirements, your shell will leave the pattern alone and pass it directly to echo which will again echo it out, resulting in this output:

[aeiou]?*[0-9]/

You can adjust that slightly in bash, by setting the "nullglob" option, which tells bash that when there are no (null) matches (globs), to remove the pattern, in which case nothing would be passed to echo, which would then just print a blank line. Or use the failglob option for the failing glob to trigger an error.

  • 1
    Methinks ` * ` "Matches any string, including the null string. ", so you may want to slightly revise the fourth item in your list? – RudiC Oct 22 '18 at 10:01
  • Thanks to @RudiC for catching the incorrect explanation; I'd missed the '?' in the list as well. – Jeff Schaller Oct 22 '18 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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