Author image Joseph Brenner


relate - list files matching the given search terms (a wrapper around locate)


   An example:

      relate bozotech lib report data

   Would match:



  relate [options] term1 [ term2 [ term3 ... ]]

     -i                 ignore case
     --ignore-case      same
     -a                 all results (suppresses standard filter)
     --all              same
     -d                 only list directories
     -dirs              same
     -f                 only list files
     -files             same
     -l                 only list symlinks
     --links            same
     -r                 treat even the first term as a regexp (albeit POSIX)
     --regexp           same
     -D                 debug messages on
     --debug            same
     -h                 help (show usage)
     -v                 show version
     --version          same

     --database '...'   Use alternative locate database(s)
     --locate   '...'   Invoke locate program differently (default: 'locate').


The mnemonic is that relate makes the file system a little more relational and a little less hierarchical (but "relate isn't really").

Instead of typing this:

  locate this | egrep "with_this" | egrep "and_this" | egrep -v "but_not_this"

You can just type:

  relate this with_this and_this -but_not_this

So essentially this script is the equivalent of

  locate primary_term | egrep term2 | egrep term3 [....| termN]

Though it also has a few other features, relate:

  o  screens out "uninteresting" files by default (emacs backups, CVS/RCS files)
  o  has options to restrict reports to files, directories or symlinks.

An important performance hint: you can speed up relate tremendously by using a relatively unique first term. For example, if you're on a unix box, you don't want to start with something like "home" or "lib" which is going to match a huge number of files in the locate database. You'll find that "relate gdk lib" is faster than "relate lib gdk".

The first term should be a simple string (unless you've used the "-r" option), but all the following terms are perl regexps. If you do use the "-r" option, than the first term is a POSIX regexp (it has no effect on the following terms).

(This inelegant state of affairs is the result of working as a wrapper around the locate command; the first term is fed to it directly, then the output is filtered using perl pattern matches.)

reverse match

A leading minus can be used to indicate a reverse match (just as with many web search engines). This is much like a "grep -v": it filters out lines that match it. This can't be used on the first term, only on the secondary ones.

For example:

   relate my_site index -htm$

will screen out files ending in "htm" (but not "html").

standard filter

This script has the extremely useful feature of automatically omitting uninteresting files, but it's guaranteed that you'll be confused by this some day, so don't say I didn't warn you.

Remember that there's a "-a" option (also called "--all") which overrides the default filter and returns all matches.

As of this writing, by default files are ignored that match these patterns:

      '~$'       # emacs backups
      '/\#'      # emacs autosaves
      ',v$'      # cvs/rcs repository files
      '\.elc$'   # compiled elisp

The default filter can be changed by editing the ~/.relate file. (This is created the first time you run relate. It is perl code generated by Data::Dumper, which is evaled when you run relate (so be careful with the permissions on this file).

directory or file types

The -f (--files) and -d (--dirs) options can restrict the reported results to just plain files, or to just directoires, respectively.

There is also a -l (--links) option, that will restrict the listing to just symlinks.

It's expected that you will use these type restrictions one-at-a-time. At present, when multiple ones are used, one will always win-out. This behavior may change in the future.

dwim upcarets

The use of a leading "^" achor in a pattern is allowed, but it is silently transformed into a boundary match: "\b". Otherwise "^" wouldn't be very useful (consider that with full paths *all* listings match "^/"). An embedded or trailing "^" is left alone. Ditto for a "^" in front of a slash: if you ask for '^/usr/lib', maybe that's really what you want.

This feature does not (at present) work well with a minus for negation.

relate isn't really

I like this slogan as a mnemonic: "relate makes the file system a little more relational", though really this is an abuse of the term "relational".

The point though, is that using "relate" is something like doing a database query where you specify certain constraints in any order and get all records that match them. But if you can't relate, that's okay.

(Just be glad I don't think of it as "feeling your way around".)

database option

There's a special --database option that allows you to use a non-standard locate database (e.g. for testing purposes). See locate.


backwards incompatibility

This version of relate (and App::Relate) are somewhat incompatible with the earlier releases which were based on List::Filter.

The casual user may not notice any difference (outside of the speed improvement). The primary difference is in the change of the name and format of the configuration file: it is now "~/.relate" in Data::Dumper format (i.e. perl code). Formerly it was "~/.list-filter/filters.yaml" using Yaml.

The goal of these changes was to reduce non-core dependencies (for the downtrodden masses without, and to improve speed.

The older versions are still available on CPAN, though they've been re-named App::Relate::Complex and relate_complex.


Some simple benchmarking shows that this script is about twice as fast as the old List::Filter based version of relate (running on my AMD64 linux box).


Problem with eval of .relate

If you see an error message something like Problem with eval of .relate, it could be you happen to have a "~/.relate" file that wasn't generated by Data::Dumper (or you might've introduced a syntax error by manual editing).

If all else fails consider just deleting it (or moving it out of the way). The relate will create a new one you can start over with (though any user customizations will have been lost).

Can't exec "locate"

The error message Can't exec "locate" makes it sound like you don't have a "locate" program installed on your system, but it could be it's just not located in your PATH, or it may even be named differently. You can experiment with different names and/or explicit paths using the "--locate" option.

Can't locate object method "new"

An error message like this:

  Can't locate object method "new" via package "App::Relate" at /usr/bin/relate line 83.

May very well mean that you've managed to run the old version of the "relate" script (from a pre-0.04 cpan package) with the new version of App::Relate (from version 0.04 or later). Try to clean-up any old versions, and re-install the App::Relate package.


App::Relate locate

Information on perl regexps: perlre



Joseph Brenner, <>


Copyright (C) 2010 by Joseph Brenner

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See for more information.


  o  The "dwim upcarets" feature (the ^ => \b regexp variation)
     doesn't work well with leading minus (negation).