13

I'm trying to use the locate command to find files in my home folder, however whenever I try and run this I get no results:

locate -i -l 4 --regexp '^\/home\/jack\/[A-Za-z0-9\/\ ]*(My.)*$'

I've also tried ^\/home\/jack\/^(?!\.)[A-Za-z0-9\/\ ]*(My.)*$ but that returns no results either.

The file I'm looking for just to test it is /home/jack/Music/Foals/My Number.flac

I would like to exclude the results of hidden files from my search.

Mikel
  • 56,387
  • 13
  • 130
  • 149
Jack Jones
  • 131
  • 1
  • 1
  • 4
  • 2
    I am not familiar with `locate`. Does it make sense to combine `-b` (i.e. "Match only the base name against the specified patterns.") with a path in `--regexp`? Why do you escape the `/`s? – Hauke Laging Feb 25 '14 at 23:09
  • Sorry I was using a regex builder which advised I escape those characters, and I guess you're right about the -b flag, I'll get rid of it now – Jack Jones Feb 25 '14 at 23:22
  • 1
    What is `(My.)*` supposed to do? `My.*$` works. You have to escape `()` in basic REs. – Hauke Laging Feb 25 '14 at 23:27
  • 1
    You are using an extended regex. But `--regexp` takes a basic regex. Try changing `--regexp` to `--regex` (no `p`). The man page says `--regex` does extended regex matching. – Mikel Feb 26 '14 at 00:15

4 Answers4

9

This seems to do the job.

locate -ir '^/home/jack/\([^.][^/]\+/\)\+My[^/]*$'

Quotes from manual:

-i, --ignore-case Ignore case distinctions when matching patterns.

-r, --regexp REGEXP Search for a basic regexp REGEXP. No PATTERNs are allowed if this option is used, but this option can be specified multiple times.

Graeme
  • 33,607
  • 8
  • 85
  • 110
  • Under Linux, mlocate 0.26-1ubuntu2 (Ubuntu 16.04 LTS Xenial Xerus, as of 2018-02-05), the command returns the following error "locate: non-option arguments are not allowed with --regexp". mlocate is the actual package (/usr/bin/locate is a symlink to mlocate). – Hans Deragon Feb 05 '18 at 13:08
1

You could also take a different approach:

locate "My file" | grep '/home/jack' | grep -v '/\.'

I'm not sure what you're trying to do. You're using the -i flag to make it case insensitive and your regex is not very specific, you seem top want to find all files or folders that are under /home/jack and which contain MY, My, my, or mY anywhere in the file name. If so, just run

locate -i my | grep '/home/jack' | grep -v '/\.'
terdon
  • 234,489
  • 66
  • 447
  • 667
0

This should work - matches only non-hidden files and folders:

find /home/jack -name "[^.]*My.*"

even simpler - this matches files that do not have hidden directories anywhere in the directory tree. Probably this is what you want:

for f in /home/jack/**/*My.*
    do echo "$f" # or do any other command
done
jayhendren
  • 8,224
  • 2
  • 30
  • 55
  • I would prefer to use `locate`, as I'm trying to integrate it into a Python GUI to search as you type and it's faster. But thanks anyway! – Jack Jones Feb 25 '14 at 23:21
  • @JackJones you don't even need `locate` to speed up results. E.g.: `echo /home/jack/**/*My.*` – jayhendren Feb 25 '14 at 23:27
0

How locate works

The index of files that the locate command uses is only rebuilt once a day, typically. It's built by this cron job, /etc/cron.daily/mlocate. So you entries are likely just not there yet. You can re-run it if you'd like it to manually rebuild these indexes.

$ sudo /etc/cron.daily/mlocate

Using find

However you're probably better off using a command such as find to locate files in your home directory.

$ find ~ -iname "[^.]*" | head -10
/home/saml
/home/saml/isql_issue.txt
/home/saml/bbbb
/home/saml/script_name.sh
/home/saml/go_figure_book
/home/saml/go_figure_book/readme.txt
/home/saml/go_figure_book/lstopo.txt
/home/saml/go_figure_book/who_breaks_out.bash
/home/saml/hdat2
/home/saml/hdat2/hdat2_v50.iso

Using a GUI

You also might be interested in a graphical search tool. Take a look at this other U&L Q&A titled: GTK Frontend for locate which covers one such tool called Catfish. This tool can utilize both locate data as well as find commands too.

slm
  • 363,520
  • 117
  • 767
  • 871
  • 2
    I often find `locate` faster than `find` even if I have to do an `updatedb` first. As long as the database is already reasonably up to date on most systems `updatedb` won't take long. Find syntax is probably easier in this case though. – Graeme Feb 25 '14 at 23:44
  • Yeah I used it daily too, it's only on servers where I'm scripting something that I'll often switch to `find`. – slm Feb 25 '14 at 23:46
  • Yeah, should have put 'most desktop systems' – Graeme Feb 25 '14 at 23:50