Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have read the man page and other references, but I am still confused by the behavior of find with -print0 option.

-print0      This primary always evaluates to true.  It prints the pathname of
             the current file to standard output, followed by an ASCII NUL
             character (character code 0).

First command:

$ find /some/path/ -iname "*intro*jpeg" -o -iname "*intro*jpg" 2> /dev/null
/some/path//asdf199Intro-5kqlw.jpeg
/some/path/199intro-2jjaj.JPEG
/some/path/199intro-3.jpg
/some/path/wuer199intro-4.JPG
/some/path/xbzf199INTRO-1.jpg

Second command:

$ find /some/path/ -iname "*intro*jpeg" -o -iname "*intro*jpg" 2> /dev/null -print0
/some/path/136intro-3.jpg/some/path/wuer136intro-4.JPG/some/path/xbzf136INTRO-1.jpg

I can see that the the filenames from the second command are null character separated, but why do I get 3 output as opposed to 5 above?

share|improve this question
1  
Technically, they're null terminated, not null separated. (There's a NUL after every pathname, including the last one.) –  cjm Sep 29 '12 at 16:51
add comment

1 Answer

up vote 7 down vote accepted

Your first example

 find /some/path/ -iname "*intro*jpeg" -o -iname "*intro*jpg"

is not equivalent to

 find /some/path/ -iname "*intro*jpeg" -o -iname "*intro*jpg" -print

It is equivalent to

 find /some/path/ \( -iname "*intro*jpeg" -o -iname "*intro*jpg" \) -print

When your expression contains any action other than -purge, the implicit print is no longer added. You want

find /some/path/ \( -iname "*intro*jpeg" -o -iname "*intro*jpg" \) -print0 2> /dev/null

The reason that you're only getting 3 filenames is that those are the ones matched by your second condition (the one that has an action). What you typed really means

find /some/path/ \( -iname "*intro*jpeg" \) -o \( -iname "*intro*jpg" -print0 \)

Which hopefully makes it clear why only 1 side prints anything.

share|improve this answer
    
It is very clear to me now. Thank You. –  Forethinker Sep 29 '12 at 17:26
    
FYI you can simplify the find expression with: find /some/path -iregex '.*intro.*\.jpe?g'...and since there is now only one expression it will avoid the issue highlighted by cjm. –  cas Sep 30 '12 at 0:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.