Last Updated on May 18, 2022 by David
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-iname
means 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$1
means the argument that we just calledf()
with, your search term
-exec ls -1rt {} +
This tells find
to sort the output using ls
.
-exec
means execute a shell command, in this case it isls
{}
is the placeholder+
is the delimiter. If+
then all the results offind
are concatenated and passed as a whole to the-exec
command, if;
then the-exec
command 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!
Very useful
Thanks
Thank you, it’s my pleasure to be of service.
Great stuff, thanks for the post. Saved in my “tweaks” diary.
Brilliant. One very minor thing: If your shell is bash (or any posix shell, in fact), quoting/escaping the empty pair of braces (in the exec clause) is unnecessary. More info at https://unix.stackexchange.com/questions/8647 HTH, jt
Thanks, you are right, I removed the wretched cruft!