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?

1 Answer 1

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.)

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .