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

2012-08-03 Thread Bob Proulx
Martin Steigerwald wrote:
> 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.

In that case I suggest using -printf throughout.  Put an identifying
remark in the printf format string associated with that action.
For example:

  $ find . -type d -printf "%p due to -type d\n" -o -name file -printf "%p due 
to -name file\n" -o -name anotherfile -printf "%p due to -name anotherfile\n"
  . due to -type d
  ./file due to -name file
  ./anotherfile due to -name anotherfile
  ./dir due to -type d

How is that?

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

Correct.

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

The argument list is a small program that is interpreted for each file
entry.  You write the argument list as you would write a program.

> So another interesting use case:
> 
> martin@merkaba:~/Zeit/find-Test> find -printf "%s %p\n" -print -exec ls -ld 
> {} \; -delete

My first thought was "ew.." due to the "-delete" being mixed in with
the recursive operation and without any restriction.  That is
basically the same as 'rm -rf .' and feels very dangerous to me.
(Which of course won't delete '.' but will delete everything else
below it.)  It could delete a lot of files very quickly!

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

Yes.

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

Yes.  Each action returned true.  The print actions always return
true.  The exec action will pass back the exit code of the process.
If any return code is not true then the processing left to right over
the argument list will stop.

> Nice ;)

As long as that is what you wanted!  :-)

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

Of course '.' won't be removed since it can't be.  This is the same as
with 'rm -rf .' too.  (However I see that recent 'rm' doesn't allow
that use nad prints an error and exits.  Probably a good safe behavior.)

I personally only use -delete with a specific restriction such as with
a -type f or -name file1 or other type of specific targeting.  I avoid
having find recursively walk down directories and also have -delete
recursively walk down directories too.

It also feels wrong that it is recursively deleting directories that
find will in the future recurse down.  Due to buffering I think this
won't be visible with small directories.  But with large directories I
believe (but did not test) that it will produce an error when find
tries to read a directory that has been previously deleted in passing.

Using -delete automatically enables -depth.  Therefore the order of
file processing will be the order find would use with 'find . -depth'.
This is done to avoid trying to delete a directory that still contains
files.  Using -depth gives the possibility that the directory will be
emptied first.

  $ mkdir dir
  $ touch dir/otherfile
  $ find . -type d -print -delete
  ./dir
  find: cannot delete `./dir': Directory not empty
  .

  $ find . -print
  .
  ./dir
  ./dir/otherfile

  $ find . -depth -print
  ./dir/otherfile
  ./dir
  .

Bob


signature.asc
Description: Digital signature


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

2012-08-03 Thread Martin Steigerwald
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
./anotherfile
-rw-r--r-- 1 martin martin 0 Aug  2 19:57 ./anotherfile
4096 ./dir
./dir
drwxr-xr-x 2 martin martin 4096 Aug  2 19:56 ./dir
0 ./file
./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
.
martin@merkaba:~/Zeit/find-Test>

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.

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


--
To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/201208031534.02823.mar...@lichtvoll.de



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

2012-08-02 Thread 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.

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

  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.

Bob


signature.asc
Description: Digital signature


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

2012-08-02 Thread Martin Steigerwald
Hi!

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.
> Thus
> find -ls -type d -print
> will list all files, and those are directories will then print it as
> well.
> o
> 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.
> 
> 
> 4203774 drwxrwx---   2 unruhunruh4096 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 2766824
> 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 \)
.
./anotherfile./dir
0 ./file%   
 
martin@merkaba:~/Zeit/find-Test>

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% 


Now I am wondering about the order.

Why does find print "another file" before ".dir" and "file" after "another 
file"?


Bill in case you have an idea I´d happily post your answer to the list 
once again if you allow me ;)

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


--
To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/201208022246.31737.mar...@lichtvoll.de



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

2012-08-02 Thread Martin Steigerwald
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.

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
.
./dir

;)

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


-- 
To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org 
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/201208021959.09473.mar...@lichtvoll.de



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

2012-08-02 Thread Kumar Appaiah
On Wed, Aug 01, 2012 at 09:12:49PM -0500, Alex Robbins wrote:
> >Kumar
> Yes, I read the man page and I know what the -print0 option is
> supposed to do.  Notice, however, that when I executed "find
> -print0 -type d" the output (which, we both understand, is delimited
> by null characters) includes the regular file, even though I
> specified "-type d".

My bad. Sorry for missing this.

Kumar
-- 
linux: because a PC is a terrible thing to waste
(k...@cis.ufl.edu put this on Tshirts in '93)


-- 
To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org 
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: 
http://lists.debian.org/20120802115312.ga30...@bluemoon.alumni.iitm.ac.in



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

2012-08-02 Thread Slavko
Hi,

Dňa Wed, 01 Aug 2012 19:33:35 -0500 Alex Robbins
 napísal:

> I see (on a terminal screen that does not display null characters):
> ../dir./file

simple try to switch the arguments:

find -type d -print0
../dir

The print0 and others are the "expressions" (see man find) and they must be
at end of command.

regards

-- 
Slavko
http://slavino.sk


signature.asc
Description: PGP signature


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

2012-08-01 Thread Bob Proulx
Alex Robbins wrote:
> I have a directory that looks like this:
> .
> ├── dir
> └── file
> "dir" is a directory and "file" is a regular file.  I execute:
> find -type d

Here you are using the GNU find extension which allows the path to be
omitted.   In GNU find the path is optional.  In the standard find the
path must be specified.  I always specify the path.  It is portable.

> and get the output:
> .
> ./dir

Okay.

> This is the expected output.  However, when I execute:
> find -print0 -type d

It would be a lot cleaner to use -print for this example instead of
-print0.  I will use -print for illustrative purposes.  But there
isn't any difference between -print and -print0 for the issue you are
talking about.

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

> The same goes for using "-type f".  It appears as though find
> ignores the -type argument when the -print0 option is passed.  Isn't
> this a bug?

It is a bug in your usage.  Arguments are evaluated from left to right
across the command line.

  -print   -- returns true, prints the full name
  -type X  -- returns true if the type of file matches X

So with this (bad) ordering:

  find . -print -type d  # bad ordering

You get this behavior:

  -print, prints the filename.  All files are printed.
  -type d, returns true if the file is a directory.  But nothing is
  after this on the command line so this value is a noop.

That above bad ordering is exactly the same as:

  find . -print

The other way around works as you intend it.

  find . -type d -print  # good ordering

  -type d, returns true if the file is a directory.  By returning true
  processing continues across the line.  By returning false processing
  stops and the action skips to the next file.
  -print, prints the file name, returns true

Does that help to make sense?

Bob


signature.asc
Description: Digital signature


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

2012-08-01 Thread kushal . kumaran+debian
Alex Robbins  wrote:

>I have a directory that looks like this:
>.
>├── dir
>└── file
>"dir" is a directory and "file" is a regular file.  I execute:
>find -type d
>and get the output:
>.
>./dir
>This is the expected output.  However, when I execute:
>find -print0 -type d
>I see (on a terminal screen that does not display null characters):
>../dir./file
>
>The same goes for using "-type f".  It appears as though find ignores 
>the -type argument when the -print0 option is passed.  Isn't this a
>bug?
>

The -print or -print0 option needs to follow the selection criteria, such as 
-type. 

I'm pretty sure this is documented somewhere in the findutils manual. 

-- 
regards,
kushal


-- 
To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org 
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: 
http://lists.debian.org/d416e2dc-c3f4-4361-a324-b5276366f...@email.android.com



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

2012-08-01 Thread Alex Robbins

On 08/01/2012 08:41 PM, Kumar Appaiah wrote:

On Wed, Aug 01, 2012 at 07:33:35PM -0500, Alex Robbins wrote:

.
./dir
This is the expected output.  However, when I execute:
find -print0 -type d
I see (on a terminal screen that does not display null characters):
../dir./file

The same goes for using "-type f".  It appears as though find
ignores the -type argument when the -print0 option is passed.  Isn't
this a bug?

No. If you refer to the man page, it will reveal that -print0 actually
outputs null characters instead of newlines. It is usually useful in
conjunction with the -0 option for xargs to run commands on each file
or directory found by find. Please read the man pages and they have
nice examples at the bottom.

Kumar

Yes, I read the man page and I know what the -print0 option is
supposed to do.  Notice, however, that when I executed "find
-print0 -type d" the output (which, we both understand, is delimited
by null characters) includes the regular file, even though I specified 
"-type d".



--
To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org 
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Archive: http://lists.debian.org/5019e221.80...@gmail.com



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

2012-08-01 Thread Kumar Appaiah
On Wed, Aug 01, 2012 at 07:33:35PM -0500, Alex Robbins wrote:
> .
> ./dir
> This is the expected output.  However, when I execute:
> find -print0 -type d
> I see (on a terminal screen that does not display null characters):
> ../dir./file
> 
> The same goes for using "-type f".  It appears as though find
> ignores the -type argument when the -print0 option is passed.  Isn't
> this a bug?

No. If you refer to the man page, it will reveal that -print0 actually
outputs null characters instead of newlines. It is usually useful in
conjunction with the -0 option for xargs to run commands on each file
or directory found by find. Please read the man pages and they have
nice examples at the bottom.

Kumar
-- 
Absolutely nothing should be concluded from these figures except that
no conclusion can be drawn from them.
-- Joseph L. Brothers, Linux/PowerPC Project)


-- 
To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org 
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: 
http://lists.debian.org/20120802014159.gb12...@bluemoon.alumni.iitm.ac.in



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

2012-08-01 Thread Alex Robbins

I have a directory that looks like this:
.
├── dir
└── file
"dir" is a directory and "file" is a regular file.  I execute:
find -type d
and get the output:
.
./dir
This is the expected output.  However, when I execute:
find -print0 -type d
I see (on a terminal screen that does not display null characters):
../dir./file

The same goes for using "-type f".  It appears as though find ignores 
the -type argument when the -print0 option is passed.  Isn't this a bug?



--
To UNSUBSCRIBE, email to debian-user-requ...@lists.debian.org 
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Archive: http://lists.debian.org/5019cadf.8050...@gmail.com