Basic examples

Find files by name

Find files in current path and its subdirectories which has FooBar in its file name:

$ find . -name *FooBar*

Allow both FooBar and foobar to be found by ignoring letter case:

$ find . -iname *FooBar*

or

$ find . -iname *foobar*

Find empty directories

find . -type d -empty

Find broken symbolic links

find -L . -type l

Remarks:

  • -L option let find resolve/follow symbolic links when possible.
  • -type l option selects only symbolic link files.

Only symbolic link files whose destination is missing or itself a symbolic link file will be found.

Find symbolic links matching a pattern

Find in the current path any symbolic link whose name contains 'foobar':

find . -lname '*foobar*'

Case-insensitive:

find . -ilname '*foobar*'

Find duplicate files

In a bash script:

#!/usr/bin/env bash

FILENAME=`basename $0`

DATETIME=`date +%Y%m%d%H%M%S`

TMPFILE=`mktemp /tmp/${FILENAME}.${DATETIME}` || exit 1

find . \! -type d -exec cksum {} \; | sort | tee $TMPFILE | cut -f 1,2 -d ' ' | uniq -d | grep -if - $TMPFILE | awk '{print $3}'

Comment:

  • - is Bash special character which means redirection from/to stdin or stdout

  • tee $TMPFILE copies stdout stream into the temporary file and pass along it through a pipe

  • uniq -d keeps the duplicated entries, i.e. files with same checksum value and file size

Find large backup files to delete to free up disk space

$ find data -name *~ -size +100000k -exec ls -lhtc '{}' \;
-rw-r--r--  1 foobar  _lpoperator   390M May  7 21:30 data/file1.txt~
-rw-r--r--  1 foobar  _lpoperator   253M May  7 21:30 data/file2.txt~
$ find data -name *~ -size +100000k -exec rm -i '{}' \;
remove data/file1.txt~? y
remove data/file2.txt~? y

Find large files

Say your disk is running out of space and you want to find the large files which potentially can be removed:

$ find -P -O2 . -type f -size +100M -user $USER -exec ls -sh '{}' >> $OUTPUTFILE \;

  • -P: use option to never follow symbolic links

  • -O2: use option to apply query optimization level 2, not available for some platforms including macOS 10.6

  • .: search in current path

  • -type f: test file type is regular file

  • -size +100M: test file size is larger than 100M

  • -user $USER: test file owner is $USER

  • -exec ls -sh '{}' >> $OUTPUTFILE: execute command to save info to file

Find .DS_Store files and remove them from version control repository

Suppose we use git

$ find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatch -f
rm '.DS_Store'
rm 'Computing/.DS_Store'
rm 'Computing/Programming/.DS_Store'
rm 'Computing/Programming/Cpp/.DS_Store'
rm 'Computing/Software/.DS_Store'
rm 'Project/.DS_Store'

Remarks:

  • -print0: print all output on same line

  • -f: to force removal

  • --ignore-unmatch: perform removing only if the file is in the Git repository

Find recently modified files in a directory recursively

find . -type f -exec stat -f "%m%t%Sm %N" '{}' \; | sort -rn | head -20 | cut -f2-

If one installs GNU find, i.e. the findutils package on MacPorts, one can use its -printf option to print access time in sortable form and them sort the lines numerically:

gfind . -type f -printf '%A+\t%p\n' | sort -n

To remove the annoying fractional seconds parts:

gfind -type f -printf '%A+\t%p\n' | sed 's/\.<span class="createlink">:digit:</span>\{10\}//' | sort -n
gfind -type f -printf '%A+\t%p\n' | cut --complement -c 20-30 | sort -n

List files in a directory recursively and sort by modification time

Print files and dates:

find . -type f -exec stat -f "%m%t%Sm %N" '{}' \; | sort -rn | head -20 | cut -f2-

Print file full paths only:

find "$PWD" -type f -exec stat -f $'%m\t%N' '{}' \; | sort -rn | cut -f2

Get the total size of files with name matching a given pattern

find . -name "foobarREGEX.txt" -ls | awk '{total += $7} END {print total}'

Notes

See also

References

External links

blog comments powered by Disqus