find is a very mighty tool. It allows you to apply a very detailed search syntax. Every Linux user should know how to use it.
Very basic usage
I told you I would start with the very basics, didn't I? So, you can need the option -iname if you want to do basic matching against the filename. The * can be used as a placeholder.
Redirecting errors
You might get some "Permission denied" errors. They are very bothersome if you combine commands in the bash. So you redirect them to /dev/null, a special file which discards everything it gets:
Real life example
I am also a developer who likes to have good names for constants, database tables and variables. Sometimes, like today, I think it's time to change a database table a bit. It got a lot more rows and the old name doesn't really fit any longer. I used a constant for the table name in all scripts. This constant was SOFTWARE_USER_TABLE and should now be USER_INFO_TABLE. So I have to search recursively and case-sensitive in my project and replace all occurrences in all strings by the new string. Except for .svn-directories, of course. The easiest way to achieve this is via find, xargs and sed:
find . -path '*/.svn' -prune -o -type f -print0 | xargs -0 sed -i 's/SOFTWARE_USER_TABLE/USER_INFO_TABLE/g'
Now the explanation of the different commands: find:
- .: search in the current working directory
- -path '*/.svn' -prune': If a directory starting with .svn is in the path to the file, skip it
- -o: atlernative (OR)
- -type f: only search for files
- -print0: print the full file name on the standard output, followed by a null character (instead of the newline character that -print uses). This allows file names that contain newlines or other types of white space to be correctly interpreted by programs that process the find output. This option corresponds to the -0 option of xargs.
xargs -0: exchanges the arguments. -0 means that input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken lit erally). Disables the end of file string, which is treated like any other argument. Useful when input items might contain white space, quote marks, or backslashes. The GNU find -print0 option produces input suitable for this mode. sed:
- -i: edit the given file in-place. If you would not use -i, it would just print everything in standard output
- /g: edit the file globally. If you would not use g, sed would only replace the first occurrence of SOFTWARE_USER_TABLE
Snippets
move all files in subdirectories to a single directory:
find -type f -exec mv {} collection/ \;
find all files which are bigger than 20MB and print their location and size. Maybe you could use du for this one, but I don't know how:
find / -type f -size +20000k -exec ls -lh {} \; 2>/dev/null | awk '{ print $5 ":\t" $8 }'
find files in the home folder owned by alice:
find /home -user alice
Further reading
Note that you should use grep if you want to search for patterns in single files.