When I am using wildcards with ls command, it works.
$ ls '*.{mp3,ogg}'  # Showing only two formats in the command
cannot access *.mp3: No such file or directory
1.ogg 2.ogg 3.ogg
but using find command doesn't work
$ find ~ -iname '*.{mp3,ogg}'
What is the error in the line?
I think this should work for you
   find ~ -name "*.mp3" -o -name "*.ogg"
-o is equivalent to boolean or
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.
This one provides you with even those files which do not have mp3 or audio extension.
find -print0 | xargs -0 file -F '//' | awk -F '//' 'tolower($2) ~ /audio/ { print $1 }'
which interprets to:
find . -print0 
Find (list) every file and output with a null terminator
xargs -0 file -F '//' Run file(1) with the stdin (or piped input),  delimited by null character,   as the first argument.
file -F '//' Delimit file name and its type by // as it neither appears in a UNIX filename nor as a file type.
awk -F '//' '...'  Use the // delimiter as field separator. The awk script case-insensitively matches the occurrence of audio in the second field (ie the file type as reported by file(1)) and for every match, prints the file path.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With