I am learning the wildcards recursive globbing and tried

$ ls **/* | wc -l
$ ls */** | wc -l

They output identical results.

Is there any distinction between **/* and */**?


*/** will only match directories (and their subdirectories & files); it will not match files (non-directories) in the current directory, because the */ portion of it requires a directory prefix before beginning the ** globstar expansion. As for **/*, the trailing /* is extraneous, since the ** will, by itself, expand to every file and directory under the current directory (subject to the dotglob option). Since every directory has been expanded by that point, the trailing /* does not match anything.

Be careful using ls to test, since it will "helpfully" read into any directories that you might pass it; consider instead something like:

printf "%s\n" */**
printf "%s\n" **/*

Also note that piping to wc -l could mislead you for actual counts; consider:

$ touch a $'b\nc'
$ ls -1
$ ls | wc -l
3     ## WRONG!
  • Also beware that in zsh (the original implementation of recursive globbing), ** alone is not special (it's the same as *), only **/ is (short for (*/)#). The API is different again in fish. See The result of ls * , ls ** and ls *** for details. – Stéphane Chazelas Oct 31 '18 at 16:19
  • 1
    The ls **/* | wc -l issues can be worked around by using ls -qd -- **/* | wc -l – Stéphane Chazelas Oct 31 '18 at 16:22

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.