Re: GNU find: "print0" and "-type" arguments
- To: email@example.com
- Subject: Re: GNU find: "print0" and "-type" arguments
- From: Martin Steigerwald <Martin@lichtvoll.de>
- Date: Thu, 2 Aug 2012 22:46:31 +0200
- Message-id: <201208022246.31737.Martin@lichtvoll.de>
- In-reply-to: <20120802192121.BE44BE863F@wormhole.physics.ubc.ca>
- References: <jtRVD-5TQfirstname.lastname@example.org> <ju7QLemail@example.com> <20120802192121.BE44BE863F@wormhole.physics.ubc.ca> (sfid-20120802_215433_158800_BB1A310E)
Bill Unruh allowed me to post his personal answer to the list. He answered
personally cause otherwise he would get the whole mailing list in the mail
instead due to some newsgroup gateway stuff.
On Thursday, 2. August 2012 he wrote:
> In linux.debian.user, you wrote:
> > Am Donnerstag, 2. August 2012 schrieb Bob Proulx:
> >> > I see (on a terminal screen that does not display null
> >> > characters): ../dir./file
> >> You have the order of arguments backwards. You wanted to say this:
> >> find -type d -print
> >> That would do the right thing. Doing it the other way around
> >> doesn't make any sense.
> Sure it makes sense. It says, take the name print it, then if that is
> successful, test if it is a directory.
> find -ls -type d -print
> will list all files, and those are directories will then print it as
> Eg here is part of the output from that command. Note that all of the
> directories have both the ls -l listing and the name printed out, while
> the files only have the first.
> Of course if by "it does not make sense" you meant that if the -type d
> was at the end of the list of find commands, it would have no
> consequences for the output, then you are right.
> 420377 4 drwxrwx--- 2 unruh unruh 4096 Jul 25 17:22
> ./.urpmi-500/rpms ./.urpmi-500/rpms
> 293597 172 -r--r--r-- 1 root root 175070 May 18 14:20
> ./acroread-plugins-weblink-9.4.6-0.1-mdv2011.0.i586.rpm 276682 4
> drwx------ 4 root root 4096 Jul 31 12:05
> ./systemd-namespace-cBR4sm ./systemd-namespace-cBR4sm
I thought find would work that way first and then chose to think otherwise
due to my own tests which didn´t take the implicit "and" in account:
> > I think doing it the other way around will just use -print0 on
> > everything since no criteria yet specified and then apply the filter
> > and then probably do nothing as an action has already been specified
> > (hence no implicite -print at the end).
> > Well more so, find seems to stop at the first action:
> > martin@merkaba:~/Zeit> mkdir find-Test
> > martin@merkaba:~/Zeit> cd find-Test
> > martin@merkaba:~/Zeit/find-Test> ls
> > martin@merkaba:~/Zeit/find-Test> mkdir dir
> > martin@merkaba:~/Zeit/find-Test> touch file
> > martin@merkaba:~/Zeit/find-Test> touch anotherfile
> > martin@merkaba:~/Zeit/find-Test> find -type d -print -name "file"
> > -printf "%s %p" -name "anotherfile" -print0
> Uh, remember that any entry goes through the list. Thus the -type d
> weeks out everything but directories and applies the following criteia
> to that. The rule is that there is an implicit "and" between the items.
> find -type d "and" -print "and" -name file "and" -print "%s %p" "and"
> -name "anotherfile" "and" -print0
> There is no file whose name is both file and anotherfile. So, on the
> direcory "dir" it passes the first test, it passes the second test
> (which is "have I printed it out") it fails the third, and the
> terminates the commmands because of the logical "and"
> On "file" it fails the first test, since it is not a directory. On
> anotherfile similarly.
> f you wanted "or" ratehr than "and" you have to explicitly put in a -o
> (for or) between the tests.
> find (-type d -print) -o ( -name "file" -printf "%s %p" ) -o ( -name
> "anotherfile" -print0 )
With some escaping gives:
martin@merkaba:~/Zeit/find-Test> find \( -type d -print \) -o \( -name
"file" -printf "%s %p" \) -o \( -name "anotherfile" -print0 \)
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
Now I am wondering about the order.
Why does find print "another file" before ".dir" and "file" after "another
Bill in case you have an idea I´d happily post your answer to the list
once again if you allow me ;)
Martin 'Helios' Steigerwald - http://www.Lichtvoll.de
GPG: 03B0 0D6C 0040 0710 4AFA B82F 991B EAAC A599 84C7