The 'find' command is one of my most used commands. The output of this command tells me that it's my 5th most used after cd, ls, vim, and grep:
▶ history | awk '{print $2}' | sort | uniq -c | sort -rn | head
It has a reputation of being difficult to use.
▶ history | awk '{print $2}' | sort | uniq -c | sort -rn | head
It has a reputation of being difficult to use.
First off, the name 'find' can confuse people a bit. What find really does is recursively list all files under the current directory (or provided path), applying filters and performing actions on that list.
Probably the most common use case is to find files with a particular name. You can do that with the -name option. It supports wildcards too. To find all the *.txt files under the current path you'd do:
▶ find . -name '*.txt'
▶ find . -name '*.txt'
You can control how deep find recurses with the -mindepth and -maxdepth options. If you wanted to list files and directories that are directly contained by subdirs of the current directory (i.e. a depth of 2), you could use:
▶ find . -mindepth 2 -maxdepth 2
▶ find . -mindepth 2 -maxdepth 2
You can also filter based on the type of file with -type; using '-type f' for files, 'd' for directories, 'l' for symlinks, and a bunch more. To find just directories it'd be:
▶ find . -type d
▶ find . -type d
There's a bunch more filters that are really useful too; -mtime to filter by last modified time, -perm to filter by file permissions, -empty for empty files, or -size to filter by file size. E.g. find files bigger than 20MB:
▶ find . -size +20M
▶ find . -size +20M
You can combine pretty much as many filters as you'd like. So if for *reasons* you'd like to find executables owned by root with the setuid bit set (-u=s) you could use:
▶ find . -executable -perm -u=s -user root
▶ find . -executable -perm -u=s -user root
This is all great for finding files, but what about actually doing stuff with them? If you want an overview of the files like ls would give you, you can use the -ls option:
▶ find . -type f -ls
▶ find . -type f -ls
The most powerful one though, is the -exec option. It lets you execute a command for every file, using '{}' as a placeholder for the path. E.g. to run the 'file' command against them all:
▶ find . -type f -exec file {} \;
▶ find . -type f -exec file {} \;
The syntax for -exec trips people up pretty often, but it's actually not *that* bad. The '{}' means "put the filename here", and you need a ';' to end the command, but ';' means something to your shell too so it must be escaped with a '\'
There is a *ton* more that find can do (and it works great with xargs; but I think that's for another thread :)) - and I actually recommend reading the man page. Hopefully these examples will help you to get started with it though :)
Loading suggestions...