Skip to main content

The find command finds files under the given directory tree, recursively.

##
# Several types of files can be searched for:
#   b    block (buffered) special
#   c    character (unbuffered) special
#   d    directory
#   p    named pipe (FIFO)
#   f    regular file
#   l    symbolic link
#   s    socket
#   D    door (Solaris)
##

# To find files by case-insensitive extension (ex: .jpg, .JPG, .jpG):
find . -iname "*.jpg"

# To find directories:
find . -type d

# To find files:
find . -type f

# To find files by octal permission:
find . -type f -perm 777

# To find files matching path pattern:
find root_path -path '**/lib/**/*.py'

# To find files with setuid bit set:
find . -xdev \( -perm -4000 \) -type f -print0 | xargs -0 ls -l

# To find files with extension '.txt' and remove them:
find ./path/ -name '*.txt' -exec rm '{}' \;

# To find files with extension '.txt' and look for a string into them:
find ./path/ -name '*.txt' | xargs grep 'string'

# To find files with size bigger than 5 Mb and sort them by size:
find ./ -size +5M -type f -print0 | xargs -0 ls -Ssh

# To find files bigger thank 2 MB and list them:
find / -type f -size +20000k -exec ls -lh {} \; | awk '{ print $9 ": " $5 }'

# To find files modified more than 7 days ago and list file information
find . -type f -mtime +7 -ls

# To find symlinks owned by a user and list file information
find . -type l --user=username -ls

# To run a command for each file, use {} within the command to access the filename:
find root_path -name '*.py' -exec wc -l {} \;

# To search for and delete empty directories
find . -type d -empty -exec rmdir {} \;

# To search for directories named build at a max depth of 2 directories
find . -maxdepth 2 -name build -type d

# To search all files who are not in .git directory
find . ! -iwholename '*.git*' -type f

# Find all files that have the same node (hard link) as MY_FILE_HERE
find / -type f -samefile MY_FILE_HERE 2>/dev/null

# To delete files by name, older than a certain number of days:
find root_path -name '*.ext' -mtime +180 -delete

# To find empty files or directories:
find root_path -empty

# To find files matching more than one search criteria:
find root_path -name '*.py' -or -name '*.r'

# To find files matching path pattern while excluding some certain path:
fnd root_path -name '*.py' -not -path '*/site-packages/*'

# -----------------------------------------------------------------------------

# To delete all '.svn' directories, recursively start in the current working directory:
find . -type d -name '.svn' -exec rm -rf "{}" \;

# copy all non-dot files over to new directory
find /Users/yourNameBak -maxdepth 1 ! -iname '.*' -exec cp -vfR "{}" Users/yourName \;

# delete all os x property lists for a user
find /Users/yourName/Library/Preferences -iname '*.plist' -exec rm -v "{}" \;

#  Find files modified less than 10 minutes ago
find / -mmin -10

# Find files modified between now and 1 day ago
find . -mtime 0   # (i.e., within the past 24 hours)

# Find files modified less than 1 day ago
find . -mtime -1  # (i.e., within the past 24 hours, as before)

# Find files modified between 24 and 48 hours ago
find . -mtime 1

# Find files modified more than 48 hours ago
find . -mtime +1

# Find files modified between 6 and 9 minutes ago
find . -mmin +5 -mmin -10

# Find files older than 30 days
find ./ -type f -mtime +30 # ("./" => start in the current working dir)

# Find files that are writeable by "others"
find . -perm -o=w

# Give owner "read/write" and group "read" permissions for files in "/Users/yourName"
find /Users/yourName -type f -exec chmod 0640 {} ;

# Give owner "read/write/execute" and group "read/execute" for directories in "/Users/yourName"
find /Users/yourName -type d -exec chmod 0750 {} ;

# Find files over 10 MB
find /home/somefolder/ -noleaf -type f -size +10000k 2>/dev/null -exec ls -lh {} ; | awk '{ print $5 ": " $9 }' |sort -n

# Find a file "foo.bar" that exists somewhere in the filesystem
find / -name foo.bar -print

# Find files over 10 MB
find ./ -noleaf -type f -size +10000k 2>/dev/null -exec ls -lh {} \; | awk '{ print $5 ": " $9 }' |sort -n

# Find Files Modified On Specific Date
# http://www.cyberciti.biz/faq/unix-linux-list-all-files-modified-on-given-date/
# GNU/find latest version:
find /path/to/dir -newermt "date"
find /path/to/dir -newermt "Feb 07"
find /path/to/dir -newermt "yyyy-mm-dd"

## List all files modified on given date
find /path/to/dir -newermt yyyy-mm-dd ! -newermt yyyy-mm-dd -ls
### print all *.pl ###
find /path/to/dir -newermt "yyyy-mm-dd" -print -type f -iname "*.pl"

# To find and delete all tmp files (*.tmp) in /home/vivek/projects that have
# been modified on 2013-02-07 (07/Feb/2013)
find $HOME/projects -type f -name "*.py" -newermt 2013-02-07 ! -newermt 2013-02-08 -delete
# If the file is found the path to the file will be printed as output. On most
# platforms the -print is optional, however, on some Unix systems nothing will
# be output without it. Without specifications find searches recursively
# through all directories.

# Find a file without searching network or mounted filesystems
find / -name foo.bar -print -xdev

# Find a file without showing "Permission Denied" messages
find / -name foo.bar -print 2>/dev/null

# Find a file which name ends with .bar in the current directory, search 2 directories deep
find . -name *.bar -maxdepth 2 -print

# Search directories "./dir1" and "./dir2" for a file "foo.bar"
find ./dir1 ./dir2 -name foo.bar -print

# Search for files that are owned by the user "joebob"
find /some/directory -user joebob -print
# The files output will belong to the user "joebob". Similar criteria are -uid
# to search for a user by their numerical id, -group to search by a group name,
# and -gid to search by a group id number.

# Find a file that is a certain type. "-type l" searches for symbolic links
find /some/directory -type l -print

# Search for directories that contain the phrase "foo" but do not end in ".bar"
find . -name '*foo*' ! -name '*.bar' -type d -print

# To find files that are greater than 10 MB and list them largest to smallest:
find / -xdev -size +10M | xargs ls -lS > /tmp/bigfiles.txt

# To finds files in '/var' owned by 'francois':
find /var -user francois | xargs ls -l

# To find files that are not owned by the 'wheel' group and are regular files:
find / ! -group wheel -type f 2> /dev/null | xargs ls -l

# To find files in '/sbin' that are regular files and are not executable by others:
find /sbin/ -type f ! -perm o+x | xargs ls -l

# -----------------------------------------------------------------------------

# To find files by extension:
find <root_path> -name '<*.ext>'

# To find files matching multiple path/name patterns:
find <root_path> -path '<**/path/**/*.ext>' -or -name '<*pattern*>'

# To find directories matching a given name, in case-insensitive mode:
find <root_path> -type d -iname '<*lib*>'

# To find files matching a given pattern, excluding specific paths:
find <root_path> -name '<*.py>' -not -path '<*/site-packages/*>'

# To find files matching a given size range, limiting the recursive depth to "1":
find <root_path> -maxdepth 1 -size <+500k> -size <-10M>

# To run a command for each file (use '{}' within the command to access the filename):
find <root_path> -name '<*.ext>' -exec <wc -l> {} \;

# To find all files modified today and pass the results to a single command as arguments:
find <root_path> -daystart -mtime <-1> -exec <tar -cvf archive.tar> {} \+

# To find empty files (0 byte) or directories and delete them verbosely:
find <root_path> -type <f|d> -empty -delete -print

# -----------------------------------------------------------------------------

copy_regular_file() {
    if [ -f "$1" ]; then
        echo "Copying regular file '$1' to '$2'"
        cp -f "$1" "$2"
    fi
}

# To copy all files from the specified directory (no recursion) that exist and are regular files:
#   Hat tips: https://stackoverflow.com/a/9612232, https://www.cyberciti.biz/faq/bash-loop-over-file/, https://jonlabelle.com/snippets/view/shell/shell-file-test-operators
find </root/path> -type f -maxdepth 1 -print0 | while IFS= read -r -d '' sourcefile; do copy_regular_file "$sourcefile" "/path/to/destination/folder/"; done

# -----------------------------------------------------------------------------