Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Tricky usage of -prune with find command
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
a23d56
Tux's lil' helper
Tux's lil' helper


Joined: 29 Aug 2003
Posts: 109
Location: Charlotte, NC, USA

PostPosted: Wed Feb 04, 2004 7:31 am    Post subject: Tricky usage of -prune with find command Reply with quote

Say you want to "find" all files in /var/log, omitting the ./news and ./portage subdirectories, omitting empty files, and omitting the wtmp file. For better performance, the man page recommends using -prune to omit subdirectory trees:

Code:
pushd /var/log >/dev/null && { find ./ -maxdepth 2 \( \( -path './news' -o -path './portage' \) -prune -o -type f ! -empty ! -name wtmp \) -exec ls -ld {} \;; popd >/dev/null; }


Also suppose you want to clear those files with cp /dev/null {}, instead of just listing them with ls -ld {}. Unfortunately, although -prune omits everything beneath the subdirectories pruned, it also prints the top level directory names thus pruned:

Code:
drwxr-xr-x    2 root     root         4096 Jan 27 16:05 ./news
-rw-r--r--    1 root     root          342 Feb  4 01:02 ./syslog
-rw-r--r--    1 root     root          298 Feb  4 01:02 ./daemon.log
-rw-r--r--    1 root     root           44 Feb  4 01:02 ./messages
-rw-rw----    1 mysql    60            137 Feb  4 01:02 ./mysql/mysqld.err
drwxrwsr-x    2 root     250          4096 Feb  3 17:40 ./portage


Which is undesirable for our purpose, because we don't want to cp /dev/null {} to those subdirectories. The man page offers few clues on how to deal with this, but after reading it many times, I finally figured it out.

Find has options, tests, and actions; they all return a value, either true or false.

-prune is an action; and normally (absent the -depth option), it returns a value of true, while emitting the names of subdirectory trees thus pruned. Unfortunately in this case, we cannot change the return value of -prune from true to false.

However, the somewhat obscure "-false" test is the key to overcoming this problem. By anding the return value of -prune with a -false test, we force a result of "false", and also get the desired side effect of suppressing the names -prune emits. We need "-and -false" right after -prune; however, since "-and" is implied, we just shorten it to "-false":

Code:
pushd /var/log >/dev/null && { find ./ -maxdepth 2 \( \( -path './news' -o -path './portage' \) -prune -false -o -type f ! -empty ! -name wtmp \) -exec ls -ld {} \;; popd >/dev/null; }


Ah, that's what we wanted:

Code:
-rw-r--r--    1 root     root          342 Feb  4 01:02 ./syslog
-rw-r--r--    1 root     root          298 Feb  4 01:02 ./daemon.log
-rw-r--r--    1 root     root           44 Feb  4 01:02 ./messages
-rw-rw----    1 mysql    60            137 Feb  4 01:02 ./mysql/mysqld.err


Now we can easily change the exec command "ls -ld" to "cp /dev/null" and clear out those logfiles like we wanted!

This example of -prune is somewhat artificial, because there are other ways of achieving the same result, with the -regex test and so forth. However, in a case where you have a large subdirectory to be excluded, and truly need to use -prune for performance reasons, now you know how.

:!:
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum