Find Cheat Sheet
Find Cheat Sheet
Find is one of those under-used powertools in Linux/UNIX that will save you lots of time if you only learn how to use it. It’s tremendously powerful and helpful.
The Main Idea
Find files (everything is a file in UNIX) that meet criteria and then do something with them (or not–just looking at them is doing something with them too).
find . -type f -iname "*jazz*.mp3" -exec mv "s/ /_/g" {} +
The above command will find all mp3 files with ‘jazz’ in the title and remove spaces from their filenames. It will work on 20 files or 2000 files. If you tried to do this with your file manager, this could take forever. But this little one-liner would do it instantly.
Basic Syntax
find _pathspec_ argument . . . command {} + (or / or ;)
You start with the find command, then provide a place (pathname) to start searching from, and then specify
what matches or non-matches you want the returned files to have. Optionally, you can have each of those
returned files get a command executed on them (more than one way to do this). The last item is to terminate the
statement with a +
or a /
or a ;
.
It’s perfectly OK to simply find files meeting criteria without executing any commands on them.
The pathspec .
means recursively search the current directory structure, but you can specify /var
or /etc
or whatever you want. You can use the -mindepth
and -maxdepth
arguments to specify how deep you want to
search the filesystem.
You can supply more than one pathspec: find /var /etc -mtime 0
– find all files in both /var and /etc that have been
modified in the last 24 hours. (-mtime 0 means less than 1 day)
Arguments for find
: How can you find files?
- name:
find . -name "*waldo*"
– find all files with ‘waldo’ in the filename - iname: (case insensitive):
find . -iname "*bogus*txt"
– finds BOGUS.txt and bOgUs.TxT - type:
find . -type d
– find all directories in the current directory structure - types (c, d, s, l, p, b): files, directories, sockets, symlinks, named pipes, block file.
- permissions:
find . -type f -perm 775
– find all files with permissions of 755. Note: can also use the-perm u=rwx,g=rx,o=rx
type of syntax. - access:
find /etc -atime -3 -name "*conf"
– all files in /etc accessed within last 3 days named “conf” - access/modification/created times:
find /var/log -atime -3 -mtime -3 -ctime -3
– less than 3 days ago Note: Accesstime is the last time the file was read. Modificationtime is the last time the content of the file was changed. Changetime is the last time the file or its metadata (such as permissions or ownership) were changed - min/time:
find /etc -cmin -10
– find all files changed in /etc less than 10 min ago. - user/uname/uid (also nouser, nogroup):
find /opt -not -group root -type f -executable
– find all executable files (by current user) in /opt not owned by members of root group - size:
find ~/Music -size +100M
– find all files in ~/Music larger than 100 Megabytes - empty:
find ~/tmp -empty
– find all empty files in your personal tmp directory - regex:
find ~/Pictures -iregex '*self*' -ctime -100
– find all selfies newer than 100 days in Pictures - readable (also -executable, -writeable):
find /etc -readable -type f
– find all readable files by current user in /etc - newer:
find ~ -newer ~/.bashrc -name ".bash*"
– find bash-related config files newer than your .bashrc in your home directory and below. Note: You can also use-newer{acm}t
on this. For example, to find all files modified on the July 4th, 2014:find / -type f -newermt 2014-07-04 ! -newermt 2014-07-05
- not (!):
find ~ ! -user username
– find all files and dirs in my home file structure not owned by username.-not
and!
are the same - and/or:
find / -type d -a -name 'python*'
– find all directories below root that start with python. (-o means ‘or’). Example:find / -type d -name 'python*' -o -name 'perl*'
Doing Actions on Files Found
- delete:
find ~/tmp -name '*.sw?*' -mtime +90 -delete ;
– delete swap files older than 90 days - exec:
find ~/Music -type f -exec rename -f 'y/A-Z/a-z/' {} +
– rename all music files to have lowercase names Note: The difference between ending with ‘+’ and ‘;’ is that the ‘+’ adds all the files as arguments at once and ‘;’ adds each file found and executes the command on each file sequentially. Example:find ~ type f -name '*jazz*.mp3' -exec tar -czf jazz.tar.gz {} +
will add all mp3 jazz files into a jazz tarball, while;
will overwrite the tarball each time with each single mp3 file. Very different results, so you probably mean to do the ‘+’ rather than the ‘;’ here. - xargs:
find . -type f -name "*deleteme*" | xargs rm {} +
– delete all files with ‘deleteme’ in name. Note: you need a pipe (‘|’) with xargs. - execdir: Executes the command on the directory the file found exists in. Not sure to use this myself
- ls:
find / -type f -size +1G -ls
– Simply lists files largers than 1G so you can view details about the file - print:
find /opt -type f -executable -print
– Show all executable files beneath /opt. Note: Sometimes special characters in filenames could cause the terminal some grief. If the output is going to a terminal rather than a file, you may want to choose a formated output, using-fprint
or-fprintf
. If you want to disregard any side effects to the terminal and print characters regardless of the terminal, you could use-print0
or-fprint0
. Read the manpage for more information on this.
Error Messages
You may or may not want to remove them. For example, if you are not interested in permissions limitations in your output,
you could use find /var/log -name "*log*" -type f 2>/dev/null
, which will throw away all errors related to files you don’t have
permissions to see.
Creation Dates
Finding files by creation dates is next to impossible to do. In fact, I would say it’s a happy accident when you do. But
you can check for files that are newer or not newer than a specific file. For example, if you know the /etc/mtab
file
has not changed since the OS was installed, then you could use that as a reference for comparison for a creation date. But
would you actually know that the file has not been altered? Or should not have been? This is one of the sticky areas of
find. I usually just say you can’t find files based on creation dates, but only by when it was last changed/modified or
accessed.
Combining Arguments
I touched on -a
and -o
above, but you can get creative on how you group the commands by using ‘(‘ and ‘)’. Also, you
usually don’t have to use -a
because it’s oftentimes implicit. If you have
find . -user 'joe' -type f
it is implicit that you want only files owned by joe. You don’t need a -a
here. But, let’s say you wanted to see all files owned by
‘joe’ that were modified more than 90 days ago but not more than 100 days ago, or only those files that were modified within the last 4
days? As the logic becomes a little more complex, the ‘(‘ and ‘)’ can come to the rescue:
find / -user joe '(' -mtime +90 -a ! -mtime +100 ')' -o '(' -mtime -4 ')'
Conclusion
There are so many options and so much flexibility with find
that you can correctly infer that it’s a daily staple for
systems admins everywhere. The more you practice with it, the more indispensible you’ll find it in your day to day work at
the command line.