Ask HN: How to (instantly) search by filename in Linux?
Right now I am using a quick script to compose a somewhat complex `find` command. This is otherwise effective but quite slow. Each query takes anywhere from 1-20 seconds.
An alternative that I pursued was `mlocate`. A daily cron (or systemd timer as the case may be) script generates a database for each directory (e.g. `updatedb --database-root DIRECTORY_A --output DATABASE_A.db --require-visibility 0`). Then to search `locate --basename --database DATABASE_A.db:DATABASE_B.db:DATABASE_C.db PATTERN`. However unlike `find`, `mlocate` does not offer an ignore or '!'. I suppose I could then strip ignored paths from the output with another tool, but things are starting to get pretty hackish at this point.
Perhaps there is something like Bitbucket's Quick File Search [1]?
Or something along the lines of etsy's hound [2] but for files rather than code of course. I've been using hound for instant search of all my repos and it is quite incredible.
[1]: http://blog.bitbucket.org/2013/02/07/introducing-quick-file-search/
[2]: https://github.com/etsy/hound
17 comments
[ 4.1 ms ] story [ 47.1 ms ] threadDo you search based on pattern in the filename only, or on the pattern in the full path to the file?
I ask because my next suggestion would be to put the output of find into a database so you can have the benefit of modern indexing technologies instead of just having a linear index.
(If that works out, you might want to go the whole hog and put the objects into the database too.)
You can optimize further by adding indexes. Postgres supports indexing based on regular expressions so that if there are particular regular expressions that you often search for, you can index on that.
locate "pattern" | grep -v "antipattern"
locate is installed by default on Ubuntu and I think on most Linux distributions so I'm not sure why you need to worry about the cron jobs and all of those command line arguments, normally that's taken care of automatically (unless of course you have special requirements for when the cron job runs).
I just tried the experiment on Ubuntu 14.04 and that statement does not appear to be true. If I create a file on a mounted non-root filesystem then run updatedb followed by locate with a pattern matching that filename I get the file's path.
There are a couple of things that could be preventing this in /etc/updatedb.conf. Make sure the mounted filesystem isn't excluded by PRUNEPATHS or PRUNEFS. Also I'm not clear on what PRUNE_BIND_MOUNTS does but my guess is that if set to yes it would exclude nfs mounted filesystems.
Here: http://linux.die.net/man/1/locate
[1]: https://github.com/junegunn/fzf
# create dir structure
find /media -type d -exec mkdir -p /dev/shm/{} \;
# create file structure
find /media -type f -exec touch /dev/shm/{} \;
Then search /dev/shm/ for your files.
http://www.lesbonscomptes.com/recoll/
Haven't used it, I'm a Windows guy. I searched for "Everything for linux" (Everything by voidtools does this functionality for windows, and is fantastic).
Alternatively, can you run Everything under Wine?