[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: GNU find: "print0" and "-type" arguments

Am Freitag, 3. August 2012 schrieb Bob Proulx:
> Martin Steigerwald wrote:
> > martin@merkaba:~/Zeit/find-Test> find \( -type d -print \) -o \(
> > -name "file" -printf  "%s %p" \) -o \( -name "anotherfile" -print0
> > \) .
> > ./anotherfile./dir
> > 0 ./file%
> > martin@merkaba:~/Zeit/find-Test>
> It is inconsistent to mix -print0 with -print and -printf.  Just use
> one or the other consistently.

Well I wanted to know which action find uses in each case, had I used -
print in all the case, I could not tell a difference.

> > Which is the same as without braces:
> > 
> > martin@merkaba:~/Zeit/find-Test> find -type d -print -o -name "file"
> > -printf "%s %p" -o -name "anotherfile" -print0 .
> > ./anotherfile./dir
> > 0 ./file%
> Yes.
> > Now I am wondering about the order.
> > 
> > Why does find print "another file" before ".dir" and "file" after
> > "another file"?
> You seem to be missing the basic operation of find.  The find program
> iterates across ever file and processes arguments from left to right
> for that file.  As long as the action returns true then find continues
> to process arguments from left to right.  If any argument returns
> false then processing stops for that file.  Find then proceeds to the
> next file and restarts processing arguments for the next file from
> left to right.

Yes, my understanding was find would be doing one run for each action, 
thus first dearch for »-type d« and print it, then search again for »-name 
"file« and print it and so on, but then it needed to scan the directory 
three times instead of just once.

>   find -type d -print -o -name "file" -printf "%s %p" -o -name
> "anotherfile" -print0
> For every file find processes it walks across the argument list.  For
> your example arguments it is something like this:
>   for each file do
>     if type d then
>       print
>     else
>       if name "file" then
>         printf "%s %p"
>       else
>         if name "anotherfile" then
>           print0
>         end
>       end
>     end
>   end
> Also 'find' walks through the directory in the order of the entries in
> the list.  It doesn't sort the entries first.  This means that they
> are in an arbitrary order.  They might appear in any order but the
> order will be repeatable for that particular directory.

Your explaination perfectly makes sense.

So I teach people this stuff and upto now didn´t think deeply about the 
exact order. I knew that the action follows the search criteria, but I 
never thought about the case with mutiple actions on one line.

So another interesting use case:

martin@merkaba:~/Zeit/find-Test> find -printf "%s %p\n" -print -exec ls -
ld {} \; -delete
0 ./anotherfile
-rw-r--r-- 1 martin martin 0 Aug  2 19:57 ./anotherfile
4096 ./dir
drwxr-xr-x 2 martin martin 4096 Aug  2 19:56 ./dir
0 ./file
-rw-r--r-- 1 martin martin 0 Aug  2 19:56 ./file
4096 .
drwxr-xr-x 2 martin martin 4096 Aug  3 15:27 .

martin@merkaba:~/Zeit/find-Test> find

So find execute all four actions for each search result and all the 
results are gone then.

Nice ;)

All results except for the current directory »find-Test«, which the -
delete option didn´t touch. The manpage is not clear. It writes about 
deleting files, but it »-delete« also removes empty directories. And it 
leaves the current directory alone although it is in the search results.

Martin 'Helios' Steigerwald - http://www.Lichtvoll.de
GPG: 03B0 0D6C 0040 0710 4AFA  B82F 991B EAAC A599 84C7

Reply to: