Practical Uses for the Find Command

The first thing one must do is setup some files to work with for these tutorials. Execute the commands below and we are good to go. By the by, FIND is a command line program that searches for files.

mkdir -p find-test/backup
touch MybashProgram.sh
touch MyCProgram.c
touch mycprogram.c
touch Program.c
cd find-test
for file in ./*; do
    cp $file backup/$file
done

Some things to note before we continue. The above will work just fine but for a curious issue. I use OS X and I learn that the default file system is case-insensitive while being case-preserving. This generally is of no consequence in day to day operations but it does mean that the files we created above will be missing one entry. Silly stuff eh? One more thing, when we execute any FIND commands we shall write find but we will really execute gfind. This is the GNU version of FIND that is a bit better but for license purposes cannot be supplied with OS X. You don’t have to use gfind but some things will not work as they should. Indeed, the very first example does not work.

Find Files Using Name

The basic usage of the FIND command searching a specific name : find -name "mycprogram.c". This command will grab the file in the main folder as well the backup folder.

Find Files Using Name and Ignoring Case

The same as above but case-insensitive : find -iname "MYCProgram.c. Try it out and see what happens… Hmm. Well here’s the thing we get exactly the same thing as we got before but that’s because of the case-insensitive file system we mentioned previously. Let’s make one thing clear though : you must be case-specific when using FIND.

Limit Search to Specific Directory Level Using mindepth and maxdepth

Find the passwd file under all sub-directories starting from the root directory : find / -name passwd. Sorry about that. Use sudo to sort out the ‘permission denied’ errors but really you shouldn’t run this command on a regular basis. To limit our search to the root dir and one level down try this : find / -maxdepth 2 -name passwd. Play around with other maxlevels. You can specify a range of depths like so : find / -mindepth 3 -maxdepth 5 -name passwd.

Executing Commands on the Files Found by the Find Command

The following command checks the MD5 checksum of the found files. The curly braces are replaced by the file name : find -iname "mycprogram.c" -exec md5sum {} \;.

Invert the Match

Match files that do not match the supplied term : find -maxdepth 1 -not -iname "mycprogram.c".

Finding Files by its inode Number

Every file has an unique inode number and we can use that to identify files. Create two files with the same name but add a space to the end of the second file. Use quotes to make this happen. Use ls to verify the two files : they look the same no? Try this instead ls -i1 test* and one can see the inode number by each file. We can specify an inode number as part of our FIND command : find -inum 4120262 -exec mv {} new-test-file-name \;. Bear in mind that the number I’ve provided was the specific number I got from the list command. The number you get will be different. Run ls -i1 *test* to prove the command worked. Use this command when there might be ambiguity or poorly named files.

Find File Based on the File-Permissions

You can find files based on their permissions which could prove interesting perhaps combined with the -not flag. find . -perm -g=r type f -exec ls -l {} \; the command searches the current folder for files (type -f) with read permission to ‘group’. To find files which has read permission only to group try this for size : find . -perm g=r type f -exec ls -l {} \; or to do the same thing using octal numbers find -perm 040 -type f -exec ls -l {} \;.

Find all Empty Files (zero byte file) in Your Home Directory and its Subdirectory

One can use the -empty flag to find zero byte files. To find all liked-minded files in the home directory : find ~ -empty. Probably a good idea to limit that search : find. . -maxdepth 1 -empty. Lastly, let’s search for non-hidden, zero-byte files in the current directory find . -maxdepth 1 -empty -not -name ".*". Lovely.

Finding the Top 5 Big or Small Files

Keep in mind that this command might take a while to run depending on which folder/files you choose to search. Big files : find . -type f -exec ls -s {} \; | sort -n -r | head 5, small files : find . -type f -exec ls -s {} \; | sort -n | head 5. The second command will yield a bunch of zero byte files. An alternative you could use is : find . -not -empty -type f -exec ls -s {} \; | sort -n | head -5.

Find Files Based on file-type Using Option -type

Find only socket files : find . -type s, find all directories find . -type d, find only ‘normal’ files : find . -type f, find all the hidden files find . -type f -name ".*", find all the hidden directories find -type d -name ".*".

Find Files by Comparing with the Modification Time of Other File

Show files which have been modified after the specified file. The following command lists files by date : ls -lrt. Try this out and pick a file…do you have one? Now with the file you have in mind try this command out find -newer $FILE. You should get a list of any file that is, unsurprisingly, newer than the supplied file.

Find Files by Size

find ~ -size +100M will give you any file above 100M in the home directory. The following suffixes can be used :

The + symbol means greater than, - means less than and no symbol is equivalent to.

Find Files Based on Modification Time

There are two options for modification time : -mmin n and -mtime n. The former searches for file’s modified ‘n’ minutes ago while the latter searches for the same thing but ‘n’ * 24 hours. An example : find . -mmin -60 will find all finds in all subdirectories that have been updated within the last hour.

find / -mtime -1 will search for all files modified within the last 24 hours.

Find Files Based on Access Time

Similar to the above we can search for access time rather than modification. We do this using -amin n and -atime n which operate exactly the same as the modification searches. Some examples : find -amin -60 & find -atime -1 operate as above but based on access time rather than modification time.

Find Files Based on Change Time

The same as the above two but with the flags -cmin n & -ctime n.

Find Files Which are Modified After Modification of a Particular $FILE

One can search for files based on the modification of another file. This could prove useful to use a file as a milestone. find -newer /etc/passwd will find any files modified after ‘etc/passwd’. On a similar note, one can find files that have been accessed after the modification of a particular file : find -anewer /etc/hosts. Lastly the same thing will of course be true of changed files : use the -cnewer flag to find files changed after another files modification.

Running Commands on Find Results

As we’ve seen with some previous examples, you can use the -exec flag to run external commands on the results of the FIND command. A simple example might be to list the FIND results in a different format : find -mmin -60 -exec ls -l {} \;.

Search Within the Current File System

The issue with searching from the root (‘/’) is that it will search through ‘/Volumes/’ which might contain mounted network shares and external hdds. The flag -xdev will search the current file system but no others, handy!

Using Multiple

The ‘{}’ braces are a stand in for the files that have been found : a variable. You can use the braces more than once in a command : find -name "*.c" -exec cp {} {}.bak \;. This command will find any file with a ‘c’ extension and copy it with ‘bak’ extension added on.

Suppressing Errors

While it’s pretty important to see any errors that crop up you might not want to see them (?). In any case you might have seen a couple of ‘Permission denied’ that may well annoy you so let’s suppress : find / -name "*.conf" 2>>/dev/null. Just remember that annoying error messages are there for a reason…