When trying to solve a problem using Linux you can rest assured that someone has come across it before, and probably solved it back in the seventies.
Everyone needs to search their hard drive for files and open them in a program of their choice. Using a mouse-driven desktop file explorer is terdious, so what is the best way to do it without leaving the beloved terminal?
There are a lot of command-line ‘fuzzy finders’ that all vie for your attention. Don’t waste your time, Linux has the find command built-in and it can do basic fuzzy file searching in one line! You just need to unravel the cryptic syntax and wrap it up in a function.
How to add a function to your .bashrc file
When Linux boots into your user account it will read the .bashrc file in your home directory. You can put your own custom command line functions in it. Add:
f() { find . -iname "*$1*" -exec ls -1rt {} +; } 2>/dev/null
To reload the file so you can access the function without rebooting type source ~/.bashrc.
How to use the f() function
When you use the new f command followed by a part of a file name it will:
- Search the current directory and all subdirectories for files whose names contain that string.
- Display those files sorted in reverse order by modification date.
- The result will include the full path, and will wrap the path with quotes when needed. This is so you can use the result directly when piping.
As an example, if you were looking to search for all files with a .md extension in your Documents folder you would first cd into the folder then type f .md.
[user@computer Documents]$ f .md
./break-up-google.md < 3rd most recently modified
./todo.md < 2nd most recently modified
'./health/workout.md' < most recently modified
How the f() function works
The syntax for a bash function is simply:
name() {}
In our tersely named f function, we see at the end:
f() {} 2>/dev/null
This means redirect errors, 2, into /dev/null rather than to the standard output, 1. This is important as otherwise, we would get Permission denied results from places we almost certainly don’t want to look anyway.
find . -iname "*$1*"
.means the current directory-inamemeans search for a case insensitive file name" "wraps what we are searching for, check out https://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-shell-variable* *wildcards mean we can have anything before or after, so we are searching for just one part of a filename$1means the argument that we just calledf()with, your search term
-exec ls -1rt {} +
This tells find to sort the output using ls.
-execmeans execute a shell command, in this case it isls{}is the placeholder+is the delimiter. If+then all the results offindare concatenated and passed as a whole to the-execcommand, if;then the-execcommand will be repeated for each result
-t sort by modification time
-r reverse order while sorting (--reverse )
-1 list one file per line
A deeper explanation of how -exec works in find can be found at
https://www.baeldung.com/linux/find-exec-command
Conclusion
Now you can locate any file you want on your hard drive in a quick and easy fashion without relying on any 3rd party dependencies.
If you need more advanced functionality you might like to check out https://github.com/junegunn/fzf, but please don’t bloat your Linux installation!