Berkeley added a handy feature to its
find
command - if you give it a single argument, it will search a database for file or
directory names that match.
(If your system doesn't have this feature, see the
locate
utility below.)
For example, if you know there's a file named
MH.eps
somewhere on
the computer but you don't know where, type:
%
find MH.eps
/nutshell/graphics/cover/MH.eps
The database is usually rebuilt every night.
So, it's not completely up-to-date, but it's usually close enough.
If your system administrator has set this up, the database usually lists
all files on the filesystem - although it may not list files in
directories that don't have world-access permission.
If the database isn't set up at all, you'll get an error like
/usr/lib/find/find.codes: No such file or directory
.
(If that's the case, you can set up a "fast
find
" database yourself.
Use GNU
locate
, below, or see
article
17.19
.)
Unless you use wildcards, fast
find
does a simple string search, like
fgrep
(
27.6
)
,
through a list of
absolute pathnames (
14.2
)
.
Here's an extreme example:
%
find bin
/bin
/bin/ar
...
/home/robin
/home/robin/afile
/home/sally/bin
...
You can cut down this output by piping it through
grep
(
27.1
)
,
sed
(
34.24
)
,
and so on.
All the fast
find
commands I've used have an undocumented feature, though:
they can match
shell wildcards (
*
,
?
,
[]
) (
15.2
)
.
If you use a wildcard on one end of the pattern, the search pattern is
automatically "anchored" to the opposite end of the string (the end where the
wildcard isn't).
The shell matches filenames in the same way.
The difference between the shell's wildcard matching and fast
find
's
matching is that the shell treats slashes (
/
) specially: you
have to type them as part of the expression.
In fast
find
, a wildcard matches slashes and any other character.
When you use a wildcard, be sure to put quotes around the pattern so the shell
won't touch it.
Here are some examples:
-
To find any pathname that ends with
bin
:
%
find '*bin'
/bin
/home/robin
/home/robin/bin
...
-
To find any pathname that ends with
/bin
(a good way to find a file or
directory named exactly
bin
):
%
find '*/bin'
/bin
/home/robin/bin
/usr/bin
...
-
Typing
find '*bin*'
is the same as typing
find bin
.
-
To match the files in a directory named
bin
, but not the directory
itself, try something like:
%
find '*/bin/*'
/bin/ar
/bin/cat
...
/home/robin/bin/prog
-
To find the files in
/home
whose names end with a tilde (
~
)
(these are probably backup files from the Emacs editor):
%
find '/home/*~'
/home/testfile~
/home/allan/.cshrc~
/home/allan/.login~
/home/dave/.profile~
...
Notice that the fast
find
asterisk matches "dot files," too.
-
The
?
(question mark) and
[]
(square brackets) operators
work, too.
They're not quite as useful as they are in the shell because they match
the slashes (
/
) in the pathnames.
Here are a couple of quick examples:
%
find '????'
/bin
/etc
/lib
/src
/sys
/usr
%
find '/[bel]??'
/bin
/etc
/lib
locate
|
Unfortunately, not all systems have fast find.
Fortunately, the Free Software Foundation has
locate
.
It's similar to fast find, but
locate
has an advantage: you can have multiple file databases
and you can search some or all of them.
Locate
comes with a database building program. |
Because fast
find
and
locate
are
so fast, they're worth trying to use whenever you can.
Pipe the output to
xargs
(
9.21
)
and any other UNIX command,
run a shell or
awk
script to test its output - almost anything will
be faster than running a standard
find
.
For example, if you want a long listing of the files, here are two
find
commands to do it:
-d
`...`
|
%
ls -l `find
whatever
`
%
find
whatever
| xargs ls -ld
|
There's one problem with that trick.
The fast
find
list may be built by
root
,
which can see all the
files on the filesystem; your
ls -l
command
may not be able to access all files in the list.