2015.10.25 Move on and Be Blessed.wav             dummy.m4a
2015.11.17 BS Full.wav.mp3                        
2015.11.17 BS MOL.wav.mp3           

find . -name '*.mp3' -o -name '*.wav' -o -name '*.m4a' -print0

but this command works find . -name "*.wav" -o -name '*.mp3' -print0

I've been reading How to use find command to search for multiple extensions and How to convert all .wav files in subdirectories to .aac using neroAacEnc?

How come my regex version does not work? find . -regex '*\.\(.mp3\|.wav\|.m4a\)' -print0 Could I pipe this regex command into the subsequent command outlined in the second referenced post, find . -name "*.wav" -print0 | while read -d $'\0' file; do ffmpeg -i "$file" -c:a libfdk_aac -vbr 3 output.m4a "${file%wav}m4a"; done replacing the find . -name "*.wav" -print0 command?


2 Answers 2


Your question seems to be missing its beginning, but the reason your find-regex command does not work is that you need to start with .* (regex syntax for "anything") not just * (glob syntax for "anything"). You also have an extraneous . in front of your extensions.

find . -regex '.*\.\(mp3\|wav\|m4a\)' -print0

As for your pipe, it should work. Test it by putting an echo in front of ffmpeg. My instinct would be to write a function or a script that I could test on one file, or else make sure that my files do not have newlines in them. Spaces are one thing, users like them, but newlines are a pain.


Your regex doesn't work, because that's not a valid regex.

* doesn't work anything like the same in a regex. To get roughly the same behaviour, your need .* but typically you don't need anything, because a regex is a substring match anyway.

You also need to escape any . you mean to match a literal - because otherwise it means any character. Because you've escaped the first . and not the second, you're actually matching.


Which I don't think you're likely to have.


find -regex '\.(mp3|wav|m4a)$' 

Would probably do the trick.

I'm not sure why your first pattern doesn't work, because I'm not on a Unix system at the moment to double check. But I would guess it'll be because the -print0 is being applied to the last term, not all of them. By any chance you your first example -are any wav files being printed?

Because you might be needing brackets:

find \( -name '*.wav' -o -name '*.mp3' -o -name '*.m4a' \) -print0 
  • You were 39 seconds earlier :)
    – Law29
    Jan 2, 2016 at 22:50
  • what's the significance of the $ sign syntax?
    – phillipsk
    Jan 3, 2016 at 4:08
  • End of line. So won't match file.mp3.bak
    – Sobrique
    Jan 3, 2016 at 9:45
  • @phillipsk the $'\0' conveys a bare ASCII NUL to the -d option. I had never seen that before, but it works and '\0' does not.
    – Law29
    Jan 3, 2016 at 12:20
  • 1
    @Sobrique the find regex match is a match on the whole name, not just a substring. It is as if ^ and $ are implied at beginning and end.
    – Law29
    Jan 3, 2016 at 12: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.