= Find files with find The `find` command is one of the most useful Linux commands, especially when faced with the hundreds and thousands of files and folders a modern computer contains. As its name implies, `find` helps you find things, and not just by filename. Whether you're on you're own computer or you're trying to support someone on an unfamiliar system, here are X things you can do with `find` to help you locate important data. == 1. Find a single file by name When you know the name of a file, but you can't remember where you saved it, use `find` to search your home directory. Use `2>/dev/null` to silence permission errors (or use `sudo` to gain all permissions). [source,bash] ---- $ find / -name "Foo.txt" 2>/dev/null /home/seth/Documents/Foo.txt ---- == 2. Find a single file by approximate name If you can't remember the exact name of the file, or you're not sure whether something was capitalized or not, you can do a partial and case-insensitive search: [source,bash] ---- $ find / -iname "*foo*txt" 2>/dev/null /home/seth/Documents/Foo.txt /home/seth/Documents/foo.txt /home/seth/Documents/foobar.txt ---- == 3. Find everything An interesting alternative to `ls -R`: [source,bash] ---- $ find ~/Documents -ls 3554235 0 drwxr-xr-x 2 seth seth 54 Sep 14 05:36 /home/seth/Documents/ 3554224 0 -rw-rw-r-- 1 seth seth 0 Sep 14 05:36 /home/seth/Documents/Foo.txt 3766411 0 -rw-rw-r-- 1 seth seth 0 Sep 14 05:36 /home/seth/Documents/foo.txt 3766416 0 -rw-rw-r-- 1 seth seth 0 Sep 14 05:36 /home/seth/Documents/foobar.txt ---- Notice that I don't use `2>/dev/null` in this instance, because I'm only listing the contents of a https://redhat.com/sysadmin/absolute-path-and-relative-path-linux[file path] within my home directory, so I don't anticipate permission errors. == 4. Find by content A `find` command doesn't have to perform just one task. In fact, there's an option in `find` that enables you to execute a different command on whatever results `find` returns. This can be especially useful when you need to search for a file by *content* rather than by name, or you need to search by both. [source,bash] ---- $ find ~/Documents/ -name "*txt" -exec grep -Hi penguin {} \; /home/seth/Documents/Foo.txt:I like penguins. /home/seth/Documents/foo.txt:Penguins are fun. ---- == 5. Find files by type Using the `-type` option, you can find files, directories, symlinks, named pipes, sockets, and more. [source,bash] ---- $ find ~ -type f /home/seth/.bash_logout /home/seth/.bash_profile /home/seth/.bashrc /home/seth/.emacs /home/seth/.local/share/keyrings/login.keyring /home/seth/.local/share/keyrings/user.keystore /home/seth/.local/share/gnome-shell/gnome-overrides-migrated [...] ---- As long as you're using the GNU version of `find`, you can include multiple file types in your search results: [source,bash] ---- $ find ~ -type f,l -name "notebook*" /home/seth/notebook.org /home/seth/Documents/notebook-alias.org ---- == 6. List just directories A shortcoming of the `ls` command is that you can't filter its results by file type, so `ls` can be noisey if you only want a listing of directories in a path. The `find` command combined with the `-type d` option is a better choice: [source,bash] ---- $ find ~/Public -type d find ~/Public/ -type d /home/seth/Public/ /home/seth/Public/example.com /home/seth/Public/example.com/www /home/seth/Public/example.com/www/img /home/seth/Public/example.com/www/font /home/seth/Public/example.com/www/style ---- == 7. Limit listing results With hundreds of files in even a default user directory, and thousands more outside of that, sometimes you get more results from `find` than you want. You can limit the depth of searches with the `-maxdepth` option, followed by the number of directories you want `find` to descend into after the starting point: [source,bash] ---- $ find ~/Public/ -maxdepth 1 -type d /home/seth/Public/ /home/seth/Public/example.com ---- == 8. Find empty files Sometimes it's helpful to find empty files as a way to declutter: [source,bash] ---- $ find ~ -type f -empty random.idea.txt ---- Technically, you can use `find` to remove empty files, but programmatic removal of files is dangerous. For instance, forget to include `-type f` in a search for empty _files_ and you get directories in your results, so by adding a delete flag you would remove potentially important directory structures. It's vital to compose your `find` command and then verify the results before deleting. Furthermore, a misplaced delete flag in `find` can delete results before qualifying them (in other words, you can delete directories in a command intended to delete only files by placing the delete flag before the type flag.) I prefer to use `xargs` or http://LINK-TO-PARALLEL-ARTICLE[parallel] and a https://www.redhat.com/sysadmin/recover-file-deletion-linux#trashy[trash command] on the rare occasion that I remove files with `find`. == 9. Find files by age The `-mtime` option allows you to limit a search to files older than, but also files newer than, _some value_ times 24. [source,bash] ---- $ find /var/log -iname "*~" -o -iname "*log*" -mtime +30 ---- The `+` before the `-mtime` number doesn't mean to add that number to the time, it's a conditional statement that matches (in this example) a value _greater than_ 24 times 30. In other words, the sample code finds log files that haven't been modified in a month or more. To find log files modified within the past week, you can use the `-` conditional: [source,bash] ---- $ find /var/log -iname "*~" -o -iname "*log*" -mtime -7 /var/log/tallylog /var/log/cups/error_log /var/log/cups/access_log /var/log/cups/page_log /var/log/anaconda/anaconda.log /var/log/anaconda/syslog /var/log/anaconda/X.log [...] ---- You already know about the `-ls` flag, so you can combine that with these commands for clarity: [source,bash] ---- $ find /var/log -iname "*~" -o -iname "*log*" -mtime -7 -ls -rw------- 1 root root 0 Jun 9 18:20 /var/log/tallylog -rw------- 1 root lp 332 Aug 11 15:05 /var/log/cups/error_log -rw------- 1 root lp 332 Aug 11 15:05 /var/log/cups/access_log -rw------- 1 root lp 332 Aug 11 15:05 /var/log/cups/page_log -rw------- 1 root root 53733 Jun 9 18:24 /var/log/anaconda/anaconda.log -rw------- 1 root root 835513 Jun 9 18:24 /var/log/anaconda/syslog -rw------- 1 root root 21131 Jun 9 18:24 /var/log/anaconda/X.log [...] ---- == 10. Searching a path Sometimes you know the directory structure leading up to a file you need, you just don't know where the directory structure is located within the system. To search within a path string, you can use the `-ipath` option, which treats dots and slashes not as regex characters, but as dots and slashes. [source,bash] ---- $ find / -type d -name 'img' -ipath "*public_html/example.com*" 2>/dev/null /home/tux/Public/public_html/example.com/font ---- == Found it The `find` command is an essential tool for a sysadmin. It's useful when investigating or getting to know a new system, for finding misplaced data, and for https://www.redhat.com/sysadmin/find-best-friend[troubleshooting] everyday problems. But it's also just a convenience tool. You don't need a "good" reason to use `find`. If it makes a task easier to just search for something instead of traversing your system, then use `find`. It's an understated but infinitely useful tool that embodies the sublime pleasure of everyday Linux. Start using it today, and _find_ out what makes it great.