Wednesday, August 6, 2008

Find

The fundamentals behind the Unix Philosophy are :
  • All Programs do only one thing but they do it really well.
  • All programs must work together i.e. The output of one program must be able to be passed to the input of another.
  • Programs must handle text streams because that is the universal interface.

This philosophy is what makes every command in Linux so Feature rich, and the Find command is no exception. Find does one thing, and that is to find files on your system and it does it really really well.

the basics of the find command are
find -name "file1.txt"

this will search all directories from the directory that you are in and will look for the file named file1.txt

find -iname "file1.txt"

will search all directories from the directory that you are in and will perform a case insensitive search for the file named file1.txt ie it will find in its search if it exists File1.txt FiLe1.TxT, FILE1.TXT and file1.txt

find / -name "file1.txt"

will search your entire file system for file1.txt

find / -name "*.txt"

will search your entire file system for all files ending in .txt

find / -name "*able*"

will search your entire file system for all files that have able in their name.

right, now that we've got the basics out of the way.

multiple search criteria can be passed to find eg

find / -name "*.txt" -user cgerada

will search for and find all .txt files that are owned by user cgerada only.

find / -name "*.txt" -not -user cgerada

will search for and find all .txt files that are NOT owned by user cgerada (so all other users .txt files will be listed)

Right ... Moving on ................

find / -size +10M

will search your file system finding all files that are greater than 10Mb in Size.
this is extremely useful for cleaning up your hard drive of large zip archives that are taking space and are no longer needed but you do not remember were they are.

you can substitute the M for a G for gigabyte ie
find / -size +1G

will find all files on your file system that are larger than 1 GB

moving on...................

lets say you need to find a document on your system that you were working on in the last hour, you cannot remember the name of the document the only unique criteria you know is that you worked on it less than an hour ago.

find / -amin -60

will list all files that were accessed less than 60 Minutes ago

-amin = when file was last read (accessed)
-mmin = when file was last changed (modified)
-cmin = when file data or meta data last changed

if you want to look for files that were accessed more than 1 day ago use -atime instead of -amin eg

find / -atime -5
will list all files that were accessed less than 5 days ago

you can narrow down you search to find all .txt files that were accessed less than 5 days ago and are less than 1mb in size

find / -name "*.txt" -size -1M -atime -5


moving on ..................

find is able to find files that are newer or older than a known file.
lets say you want to find a file that you know was created after the time that you created file1.txt but you cannot remember the name of the file.

find / -newer file1.txt
will list all files that are newer than file1.txt.You can combine search criteria to narrow down your search eg
find / -name "*.txt" -newer file1.txt will search for all .txt files that were created after file1.txt and of course you can negate your search criteria so that you can search for all files that are older than file1.txt eg
find / -name "*.txt" -not -newer file1.txt

will find all .txt files that were created before file1.txt

moving on.......................

Find is able to execute other commands on files that it has found.
to execute other commands on the results of your search we use the
-ok or the -exec switches
lets say for example your hard disk has become full and you want to move all files that end in .zip that are bigger than 100Mb into a directory called /largefiles

find / -name "*.zip" -size +100M -ok mv {} /largefiles/ \;

the -ok switch lets you confirm each file before it is moved
if you substitute -ok for -exec then you will not be asked and the move will just take place.

I advise you to first run the command with out the -ok or -exec option which will just list the files, then if you are happy that the correct files have been listed re-run the command and add in the -exec option
the {} are place holders that will put every file it finds in the place holder and run the command on that file name .
The reason that the command ends in a \; is because find uses ; as the delimiting character and so does the bash shell so to prevent bash from interpreting the ; we need to put a \ in front of it. that way the interpreting of the ; delimiter is passed on to find.

other examples: Lets say you want to rename all .zip files on your system to .old files

find / -name "*.zip" -exec mv {}.old \;

or lets say you want to find all files on your system that end in .sh and make them all executable

find / -name "*/sh" -exec chmod 755 {} \;

remember whenever you use the -ok or -exec option your statement must end in a \;

lets say you want to be prompted before removing all of cgerada's tmp files that are over 5 days old

find /tmp -ctime +5 -user cgerada -ok rm {} \;to do the same but not be prompted you would use the -exec option like so
find /tmp -ctime +5 -user cgerada -exec rm {} \;


 this will remove all empty directories/folders

find -depth -type d -empty -exec rmdir {} \;


 flatten directory tree

This will move all the files with extension JPG in the directory tree starting at the current location to directory /home/cgerada/Pictures/2012-05-13.

find -name "*.JPG" -exec mv {} /home/cgerada/Pictures/2012-05-13 \;

This will list the filesizes of all the .zip files starting from the current directory.

find -name "*.zip" -exec du -h {} \;

This will tell you the total size of all files created from 2013-12-01 until now

find -name "*" -newermt 2013-12-01 -exec du -h {} \; | awk '{ total += $1 }END{ print total }'

2 comments:

Anonymous said...

Thank You! I just added you to my favorites!!!

CG said...

Thank you .. much apreciated :)