Sep 21, 2007

These are the most useful tips for using find.

Simplest find

$ find .
.
./a.txt
./b.txt

$ find /etc $HOME /tmp .
# find in multiple places...

If path is “.”, it seems to use relative path, not full path when retrieving filenames. Instead of using “.”, one can use pwd to get full path.

$ find `pwd`
/Users/ccp
/Users/ccp/a.txt
/Users/ccp/b.txt

List all files in current dir

find . -type f

List all directories in current dir

Find all dot files but not git dot files

find . -name ".*"  ! -name ".git*"

Find all non-dot files

find . -name '[!.]*'

Change permissions for Wordpress directory

find /path/to/your/wordpress/install/ -type d -exec chmod 755 {} \;
find /path/to/your/wordpress/install/ -type f -exec chmod 644 {} \;

Change permission, give group access to all directories

find . -type d -exec chmod g+x {} \;

Calculate size of all files using find

find . -iname "*.png" -ls | awk '{s += $7} END {print s}'
2076723

Same without awk

find . -iname "*.png" -print0 | xargs -0 du -ch | tail -1
2.2M    total

Find files that were changed in last x days/ minutes

# find files that were changed in the last 10 minutes
find / -mmin -10

# files modified between now and 1 day ago
find / -mtime -0 # days, not minutes, (within past 24 hours)
find / -mtime -1 # same as above

find / -mmin +10 -mmin -20 # find files modified between 11 and 19 minutes ago

also see -cmin, -ctime (changes made to file's node -ie permission, metadata, but not content of file)

Useful alias for find

alias f="find . -name"
 	f '*.png'		# find all png files in current dir

Test find by using echo after -exec.

find `pwd` -type d -mindepth 1 -exec echo ln -s {} ~{} ";"

exec vs pipe | xargs

xargs must be preceded by -print0 (which handles space in the filename correctly). -print0 must be the last argument of find.

find . -exec doSomething...

is same as using xargs using pipe

find . -print0 | xargs -0 ....

xargs -0 is required to force NUL instead of space
xargs -r (Linux/Gnu only) doesn't run command if stdin is empty. This prevents error where argument is missing in command. Nice to have it in Linux, but not available on BSD or Mac.

Delete files using find

Careful with delete. Always put -delete after -name, not before or it will delete ALL!!!

$find . -name *.pyc -delete # OK
$find . -delete -name ....   # WRONG! WILL DELETE ALL!!!

Better

find . -name '*.pyc' | xargs rm

The one-liner, run from the folder you want to clean (for cron, change the “.” to the volume’s path):

# http://macosx.com/forums/archive/t-28539.html
find . -name ._* -exec rm '{}' ';'

find . -name "*.pyc" -exec rm -f {} \;

3 ways to delete

find / -name "*.tmp" -print0 | xargs -0 /bin/rm -f    
	# without -print0, -0, it will fail on filename containing space. Alt: use {}+
find / -name "*.tmp" -exec /bin/rm -f '{}' \;   
find / -name "*.tmp" -delete                

There can be multiple exec in a single find, using long chaining

find -exec .... {} ";" -exec ...{} ";" -exec ...{} ";"

find options

examples

find all files which are NOT png in /tmp and its sub directories

find /tmp ! -name "*.png"

find by permission

find ~ -perm 644

find all directories (non-recursive) except “.git/”

find . -maxdepth 1 -mindepth 1 \! -name "*.git" -type d

find names and apply iconv to filename (not content of file)!! http://stackoverflow.com/questions/9930484/change-file-names-with-find-and-iconv

Misc

mac find / grep for text in resource file

$ sudo find / -type f -print0 | xargs -0 fgrep "Are you sure you want to shut down your" 2>/dev/null

References