If you enable extglob (shopt -s extglob
), you can use *.@(ogg|mp3)
.
shopt -s extglob
printf '%s\n' *.@(mp3|ogg)
If you need recursion too, enable globstar (requires bash 4.0 or newer)
shopt -s extglob globstar
printf '%s\n' **/*.@(mp3|ogg)
When you use ls *.{mp3,ogg}
, you are combining brace expansion and pathname expansion. What happens is:
ls *.{mp3,ogg}
ls *.mp3 *.ogg # after brace expansion
ls '*.mp3' 1.ogg 2.ogg 3.ogg # after pathname expansion
If there's no matching files for a glob, the glob will just be passed on unchanged. And ls
will treat it as a literal filename; it doesn't know about globs/wildcards.
The find ~ -iname '*.{mp3,ogg}'
doesn't work because find
doesn't do brace expansion, that's a bash feature.
ls *.{mp3,ogg}
to get that output, notls '*.{mp3,ogg}'
file
instead.