54

I was wondering how to restrict the search range of "locate" to some directory?

For example, how to find files/directories with string "math" in their names under some directory "/home/tim/science/"?

Thanks and regards!

5 Answers 5

35

UPDATE: A note about using locate's regex option vs the shell's filename expansion in relation to locate's args ...

SHELL FILENAME EXPANSION
When you type locate /bin/b* (note there are no quotes), several things happen.

  1. First, shell filename-expansion will expand the special shell pattern charecter * (This is because the * is unprotected, ie. there are no "double-quotes")
  2. This resulting expansion is a list of filenames. which is perhaps very long... This list is passed to locate as many individual commandline args.
  3. locate then tests each of these args against each of the files in its database, and outputs matches.

Take note however, that 'locate' has no concept of the current working directory. It only matches your args against the fully-qualified file-names in its database.
This means that it will match both /bin/bash and /home/user/bin/brackets
You have some degree of control this way, but locate's regex search offers more; as do some other of locate's options.

LOCATE'S REGEX OPTION
When you type locate -r "/bin/b.*" different things happen than do with simple args.. (shell-expanded-args are just a list of simple args)

  1. The -r option tells locate to treat your arg as a regex pattern.
  2. The quotation marks protect the * from shell filename-expansion. It means that the * and the dot . are now special regex characters
  3. Being regex, you can very easily tell 'locate' to match its database entry in various ways: eg1. locate -r "^/bin/b.*" produces file names beginning with /bin/b ... eg2. locate -r ~/"bin/b.*" produces file names beginning with /home/user/bin/b .. Note that the ~/ is not protected by "quotation-marks" and is therefore subject to shell tilde-expansion which converts ~/ into /home/user/

Summary: "shell filname expansion" is quite different to 'regex'

Now back to the original post:


locate typically lists the entire database to stdout, so to limit it to a particular directory you need to filter it... You can do this via locate's options.

You can use locate's regex capability, rather than just shell-globbing ...(locate /dir/myfile* is shell-globbing)...

From info locate: -r,--regex

  • "... (regex) matches are performed against the whole path name, and so by default a pathname will be matched if any part of it matches the specified regular expression. The regular expression may use ^ or $ to anchor a match at the beginning or end of a pathname."

note: -i = ignore case
. . . . . -r = regex
. . . . . ~/ will be expanded by the shell to /home/user (when ~/ is not in quotes)
. . . . . '\ ' (baskslash+space; no quotes) is a literal space (to avoid shell expansion). You can put the string in quotes, but be sure to leave the ~/ outside the quotes: ~/my\ regex or -/"my regex"

eg. locate -ir ~/".*"la\ bella\ vita is the same as locate -ir ~/".*la bella vita" and will search your entire home directory for "La Bella Vita" occurring anywhere.

You can also limit the search to just the file name but using the -b or --basename .. in which case the regex start-of-line ^ applies to only the basename...

I most commonly find myself using locate -bir

PS.. Locate is so fast, that I have never used find ... nor have I used nautilus search (too slow)

With 'locate', if you are looking for something which is newly added, just run sudo updatedb to refresh locate's database... (but if you've newly added it, you probably know where it is :)....

17

Pipe it through grep, like this

$ locate less | grep ^/bin
/bin/bzless
/bin/less
/bin/lessecho
/bin/lessfile
/bin/lesskey
/bin/lesspipe
/bin/zless

Edit: The other answer is better, I didn't know you can pass a pattern to locate.

6
  • @Adam.. Don't underestimate your method; it is quite okay, but you can use locate's own regex instead of piping to grep.. The "other" method you refer to does not use regex and behaves quite differently.... I've added some detail about the differences to my answer...
    – Peter.O
    Apr 3, 2011 at 20:04
  • 3
    locate less | grep ^/bin is way faster than locate -r ^/bin/.*less, because locate less will perform an efficient search for the word less, and locate -r will perform a regex operation on all the entries in locatedb Mar 17, 2016 at 17:37
  • @MarcelValdezOrozco What is "efficient search for the word" and why is it faster than regex? Feb 10, 2018 at 21:13
  • @Flashrunner Because locate does an O(log(n)) search over locatedb when you give it a non-regex search query, then you can use grep's regex to perform an O(m) search over the already reduced sub-results. (n = total number of entries in locatedb [i.e. all of your drive's files], m = # of entries that match less in your locatedb), total running complexity: O(log(n)) + O(m), where m is on average log(n), so you get 2*O(log(n)), as opposed to O(n) when you perform a regex query over all entries in locatedb. Feb 14, 2018 at 0:52
  • @MarcelValdezOrozco But why non-regex search over db is O(log(n)) while regex search is O(n)? Amount of entries in db is the same in each case. I guess it is search algorithm? Feb 14, 2018 at 16:28
9

You can use locate /rootpath/*filenamespec.I hadn't tried it before, but it appears to work. To do your example, it would be locate /home/tim/science/*math*

You may want to look at the find command rather than locate for that sort of behaviour. The syntax would be find rootforsearch -name filenamepattern -print. In this case, your example would require find /home/tim/science -name *math* -print.Not as fast as locate as there's no database to search ... it actually searches the filesystem. There are lots of options you can use other than print as well, if you intend to actually do something with the file.

2
  • This is the best answer as it uses locate itself (not requiring any other utility such as grep) and does without regexps (which are nice, but unnecessary in this case).
    – Tom
    Apr 9, 2015 at 12:37
  • This one works really like a charm that you can use locate to search files in specific directory Path, thanks @Nerdfest Mar 15, 2016 at 5:30
4

For me the most convenient is

cd /home/tim/science
locate math | grep `pwd`
1
  • Did you really read the question?
    – Trect
    Aug 11, 2019 at 17:06
1

I like to use locate --all as in perhaps locate -A tim science math. I think that is in the spirit of simplicity of locate.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .