Table of Contents
search for files in a directory hierarchy
Examples
Filtering based on file name
find . -iname 'power.log'search and print path of file named power.log (ignoring case) in current directory and its sub-directoriesfind -name '*log'search and print path of all files whose name ends with log in current directory - using.is optional when searching in current directoryfind -not -name '*log'print path of all files whose name does NOT end with log in current directoryfind -regextype egrep -regex '.*/\w+'use extended regular expression to match filename containing only[a-zA-Z_]characters.*/is needed to match initial part of file path
Filtering based on file type
find /home/guest1/proj -type fprint path of all regular files found in specified directoryfind /home/guest1/proj -type dprint path of all directories found in specified directoryfind /home/guest1/proj -type f -name '.*'print path of all hidden files
Filtering based on depth
The relative path . is considered as depth 0 directory, files and folders immediately contained in a directory are at depth 1 and so on
find -maxdepth 1 -type fall regular files (including hidden ones) from current directory (without going to sub-directories)find -maxdepth 1 -type f -name '[!.]*'all regular files (but not hidden ones) from current directory (without going to sub-directories)-not -name '.*'can be also used
find -mindepth 1 -maxdepth 1 -type dall directories (including hidden ones) in current directory (without going to sub-directories)
Filtering based on file properties
find -mtime -2print files that were modified within last two days in current directory- Note that day here means 24 hours
find -mtime +7print files that were modified more than seven days back in current directoryfind -daystart -type f -mtime -1files that were modified from beginning of day (not past 24 hours)find -size +10kprint files with size greater than 10 kilobytes in current directoryfind -size -1Mprint files with size less than 1 megabytes in current directoryfind -size 2Gprint files of size 2 gigabytes in current directory
Passing filtered files as input to other commands
find report -name '*log*' -exec rm {} \;delete all filenames containing log in report folder and its sub-folders- here
rmcommand is called for every file matching the search conditions - since
;is a special character for shell, it needs to be escaped using\
- here
find report -name '*log*' -deletedelete all filenames containing log in report folder and its sub-foldersfind -name '*.txt' -exec wc {} +list of files ending with txt are all passed together as argument towccommand instead of executing wc command for every file- no need to use escape the
+character in this case - also note that number of invocations of command specified is not necessarily once if number of files found is too large
- no need to use escape the
find -name '*.log' -exec mv {} ../log/ \;move files ending with .log to log directory present in one hierarchy above.mvis executed once per each filtered filefind -name '*.log' -exec mv -t ../log/ {} +the-toption allows to specify target directory and then provide multiple files to be moved as argument- Similarly, one can use
-tforcpcommand
- Similarly, one can use
Further Reading
- using find
- find examples on SO
- Collection of find examples
- find Q&A on unix stackexchange
- find and tar example
- find Q&A on stackoverflow
- Why is looping over find's output bad practice?
find files by name
Faster alternative to find command when searching for a file by its name. It is based on a database, which gets updated by a cron job. So, newer files may be not present in results. Use this command if it is available in your distro and you remember some part of filename. Very useful if one has to search entire filesystem in which case find command might take a very long time compared to locate
Examples
locate 'power'print path of files containing power in the whole filesystem- matches anywhere in path, ex: '/home/learnbyexample/lowpower_adder/result.log' and '/home/learnbyexample/power.log' are both a valid match
- implicitly,
locatewould change the string to*power*as no globbing characters are present in the string specified
locate -b '\power.log'print path matching the string power.log exactly at end of path- '/home/learnbyexample/power.log' matches but not '/home/learnbyexample/lowpower.log'
- since globbing character '' is used while specifying search string, it doesn't get implicitly replaced by
*power.log*
locate -b '\proj_adder'the-boption also comes in handy to print only the path of directory name, otherwise every file under that folder would also be displayed- find vs locate - pros and cons