Thursday, November 10, 2005

Finding Bliss - UNIX find Introduction

The UNIX find command is, in my book, one of the most powerful time-saving utilities ever. I would even go so far as to say that you have not appreciated the power of UNIX utilities fully unless you have used, and can habitually use, the find command.

What's more, it it offers great flexibility and power. Not only does it allow you to find stuff, but it also allows you to invoke a command you specify, on each item it finds.

1. Finding stuff
$ find /
gives you a list of everything that's under the / directory. And that, as far as your system is concerned is everything under the sun. You can replace / with any other directory of your choice.

2. Finding a file based on name
$ find / -name foo
finds all items (files and directories) named foo, on your system. You can specify wildcards if you wish but remember to escape shell expansion for the wildcard by using quotes.

3. Getting a list of all directories on your system
$ find / -type d

4. Executing a command on what find found
$ find / -exec ls -l '{}' \;
generates a detailed ls listing of each item found in the system

This needs a little bit of explanation -
-exec specifies that what follows is a command
\; denotes the end of the command
'{}' is where the current item gets substituted in the command for each item.
You can give any command you want instead of ls, of course.

1. -name, -type and -exec are like extensions to the basic find utility, which builds a list of everything under a directory. It spiders the subdirectory structure and builds a list.

2. Think of -name and -type as filter conditions for cutting the list down to just what we need. For example, -type f means files and -type d means directories.

3. -exec specifies the action to invoke on each item - whatever is between exec and \; gets taken by find as the command.

4. There are many more modifiers. Please refer to the man pages on your system. These only serve as quick but useful intros.

Let's say you want to view and edit all readme files under a directory, say, /home using an editor, say vi. Think about it.

You can accomplish this in one line with the find command.
$ find /home -type f -name readme.txt -exec vi '{}' \;

So much less troublesome, less strenuous and less time-consuming than getting a list of the files and clicking on them one by one. All in a line's work!

(external view)
find allows you to iterate over a filtered collection invoking a specified action. Call it... I'm-making-it-up....the Moulding Iterator design pattern if you will. I have found that this is an extremely common problem, it deserves a name, so forgive me!

find epitomizes the engine-addon idiom. At its heart, it is a list generator which has the capability of spidering directory structures. The list generator has unobtrusive facilities for filter conditions, to be used if needed and specifying the action to , if needed. Unobtrusive: if you want the feature, you can use it; if you don't care about it, no need to bother even knowing about it.

Flexibility=Good design. find has its limits, yes, but considering the fact that it was designed when it was, it's very, very good indeed. find out for yourself!

- Thomas Jay Cubb

No comments: