4

I am writing a little script the modifies some movies in a directory tree, and I would like to parse that tree with a bash for loop or similar.

So I started to find the files with

find -iname *.mov -or -iname *.mkv -or -iname *.avi

and he shows me some files of each kind just as expected.

But then I try to loop over the result with this (since there is whitespace in some of the dir names).

find -iname *.mov -or -iname *.mkv -or -iname *.avi -print0 | while read -d $'\0' line
do
    echo $line
done

But now he only returns the avi files! So it seems like when I add the -print0 he ignores my -or and the other -iname.

What is going on here, what am I missing?

Do I need to send the result from find into a tmpfile before looping over the result?

10

The -print0 action only attaches itself to the last test (-iname *.avi in this case). Either repeat the print action for each match, or do some grouping.

find -iname '*.mov' -print0 -or -iname '*.mkv' -print0 -or -iname '*.avi' -print0

or

find \( -iname '*.mov' -or -iname '*.mkv' -or -iname '*.avi' \) -print0

And careful with those * - from the find man page:

Please note that you should quote patterns as a matter of course, otherwise the shell will expand any wildcard characters in them.

A slightly more concise form if your find has that option:

find -iregex '.*\.\(mov\|mkv\|avi\)$' -print0

(And you might want to add -type f in case you ever find yourself naming directories with those extensions.)

  • Good point with the type f to void dirs with bad names. – Johan Dec 31 '11 at 11:53

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.