views:

1319

answers:

3

I don't quite understand the example given from the 'man find', can anyone give me some examples and explanations? Can I combine regular expression in it?


the more detailed question is like this: write a shell script, changeall, which has an interface like "changeall [-r|-R] "string1" "string2". It will find all files with an suffix of .h, .C, .cc, or .cpp and change all occurrences of "string1" to "string2". -r is option for staying in current dir only or including subdir's. NOTE: 1) for non-recursive case, 'ls' is NOT allowed, we could only use 'find' and 'sed'. 2) I tried 'find -depth' but it was NOT supported. That's why I was wondering if '-prune' could help, but didn't understand the example from 'man find'.


EDIT2: I was doing assignment, I didn't ask question in great details because I would like to finish it myself. Since I already done it and hand it in, now I can state the whole question. Also, I managed to finish the assignment without using -prune, but would like to learn it anyway.

A: 

Prune is a do not recurse at any directory switch.

From the man page

If -depth is not given, true; if the file is a directory, do not descend into it. If -depth is given, false; no effect.

Basically it will not desend into any sub directories.

Take this example:

You have the following directories

  • /home/test2
  • /home/test2/test2

If you run find -name test2:

It will return both directories

If you run find -name test2 -prune:

It will return only /home/test2 as it will not descend into /home/test2 to find /home/test2/test2

kerchingo
+9  A: 

The thing I'd found confusing about about -prune is that it's an action (like -print), not a test (like -name). It alters the "to-do" list, but always returns true.

The general pattern for using -prune is this:

find [path] [tests for stuff you want to prune] -prune -o [the stuff you'd normally put after the path]

You pretty much always want the the -o immediately after -prune, because that first part of the test (up to including -prune) will return false for the stuff you actually want (ie: the stuff you don't want to prune out).

Here's an actual example:

find . -name .snapshot -prune -o -name '*.foo' -print

This'll find the "*.foo" files that aren't under ".snapshot" directories. In this example, -name .snapshot is the "tests for stuff you want to prune", and -name '*.foo' -print is the "stuff you'd normally put after the path".

Laurence Gonsalves
+2  A: 

Beware that -prune does not prevent descending into any directory as some have said. It prevents descending into directories that match the test it's applied to. Perhaps some examples will help (see the bottom for a regex example). Sorry for this being so lengthy.

$ find . -printf "%y %p\n"    # print the file type the first time FYI
d .
f ./test
d ./dir1
d ./dir1/test
f ./dir1/test/file
f ./dir1/test/test
d ./dir1/scripts
f ./dir1/scripts/myscript.pl
f ./dir1/scripts/myscript.sh
f ./dir1/scripts/myscript.py
d ./dir2
d ./dir2/test
f ./dir2/test/file
f ./dir2/test/myscript.pl
f ./dir2/test/myscript.sh

$ find . -name test
./test
./dir1/test
./dir1/test/test
./dir2/test

$ find . -prune
.

$ find . -name test -prune
./test
./dir1/test
./dir2/test

$ find . -name test -prune -o -print
.
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

$ find . -regex ".*/my.*p.$"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test/myscript.pl

$ find . -name test -prune -regex ".*/my.*p.$"
(no results)

$ find . -name test -prune -o -regex ".*/my.*p.$"
./test
./dir1/test
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test

$ find . -regex ".*/my.*p.$" -a -not -regex ".*test.*"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py

$ find . -not -regex ".*test.*"                   .
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2
Dennis Williamson