Difference between revisions of "Findutils"

From Christoph's Personal Wiki
Jump to: navigation, search
(Change permissions on (sub)directories and files)
(Examples)
Line 22: Line 22:
 
  time find /home/foo/bar -type f -exec grep EXAMPLE {} \; -print
 
  time find /home/foo/bar -type f -exec grep EXAMPLE {} \; -print
 
  time find /home/foo/bar -type f|xargs grep EXAMPLE  # <- faster
 
  time find /home/foo/bar -type f|xargs grep EXAMPLE  # <- faster
 +
 +
* find all <code>foo.pdb</code> files in a given path and execute a command ''within'' the directory they are found:
 +
find /path/to/files/ -name foo.pdb -execdir some_command \;
  
 
* find (list) all files in a given path having "<code>Fo*</code>" in their filename:
 
* find (list) all files in a given path having "<code>Fo*</code>" in their filename:

Revision as of 21:15, 9 July 2007

The GNU Find Utilities (or Findutils) are the basic directory searching utilities of the GNU operating system. These programs are typically used in conjunction with other programs to provide modular and powerful directory search and file locating capabilities to other commands.

Findutils tools

The tools supplied with this package are:

  • find - search for files in a directory hierarchy
  • locate - list files in databases that match a pattern
  • updatedb - update a file name database
  • xargs - build and execute command lines from standard input

Examples

Note: Adapted from the GNU Project homepage.

  • Here is an example operation to make all HTML files in the subdirectory htdocs readable by all using find and xargs. This is a typical example of how find and xargs are used with other utilities to provide powerful directory traversal capability:
find htdocs -name '*.html' -print0 | xargs -0 chmod a+r 
  • Find all files in a given path a print them to the STDOUT (one file/line):
find . -name \*.htm -printf %f\\n
  • find all files in a given path containing the word "EXAMPLE" in them (time the difference):
time find /home/foo/bar -type f -exec grep EXAMPLE {} \; -print
time find /home/foo/bar -type f|xargs grep EXAMPLE   # <- faster
  • find all foo.pdb files in a given path and execute a command within the directory they are found:
find /path/to/files/ -name foo.pdb -execdir some_command \;
  • find (list) all files in a given path having "Fo*" in their filename:
find bar/ -name 'Fo*' -exec ls -l {} \+ 
  • search for files modified within the last day that match a certain filenaming pattern and remove them (i.e. execute rm):
find . -name "[Tt][Ee][Ss][Tt]*" -mtime -1 -exec rm {} \;  # CAREFUL!!

Bulk image resize

If you are like me and have a high resolution digital camera, it is often necessary to resize the images before emailing them to friends and family. It is, of course, possible to manually resize them using Adobe Photoshop, The Gimp, or any other image editing programme. However, it is possible to automate this task using simple command line tools.

For an example, say you want to resize all of the jpeg images in your current directory to 800x600 and place them in a sub-directory called, "resized". Then you would execute the following commands:

find . -maxdepth 1 -name '*.jpg' -type f -exec convert -resize 800x600 {} resized/{} \;

It is also possible to have the above commands run recursively through a directory and its sub-directories like so:

find . -follow -name '*.jpg' -type f -exec convert -resize 800x600 {} ../resized/{} \;

Note that the programme convert is part of the ImageMagick suite and you will need to have it installed to use the above commands (it is, by default, in SuSE Linux).

Tracking down large files

Sometimes it is necessary to find files over a certain size and it can be somewhat tedious ls-ing through your many directories. The following command will list only those files over a certain size and only within the specified directory (and sub-directories):

find some_directory/ -size +2000k -ls

which will only list files over 2000 kb (2 MB).

Finding files containing a string in a directory hierarchy

In this example, all .php files will be searched for the string "MySQL" (case-insensitive with -i) and the line numbers will also be returned (using -n):

find . -name '*.php' -type f | xargs grep -n -i 'MySQL'

Permissions on (sub)directories and files

  • Find files with a given permission
find /path/ -type f -perm 755
  • Change the permissions of all sub-directories:
find /path/ -type d -exec chmod 755 {} \;
#~OR~
find /path/ -type d -exec chmod u=rwx,go=rx {} \;
  • Change the permissions of all files in sub-directories:
find /path/ -type f -name "*.txt" -exec chmod 644 {} \;
#~OR~
find /path/ -type f -exec chmod u=rw,go=r {} \;

where,

-nouser: shows output that's not associated with an existing userid
-nogroup: shows output not associated with an existing groupid
-links n: file has n links
-newer file: file was modified more recently than file.
-perm mode: file has mode permissions.
-type c
       File is of type c:
       b  block (buffered) special
       c  character (unbuffered) special
       d  directory
       p  named pipe (FIFO)
       f  regular file
       l  symbolic link; this is never true if the -L option or the -follow option is
          in effect, unless the symbolic link is broken. If you want to search for 
          symbolic links when -L is in effect, use -xtype.
       s  socket
       D  door (Solaris)

Log rotate

If you do not want run-away logging to fill up your /var partition, you can archive (tar) old logs (e.g., older than one day):

find /var/log/ -name "*.log" -mtime +1 -exec bzip2 -z '{}' \;

and then delete old tars (e.g., older than 30 days):

find /var/log -name "*.bz2" -mtime +30 -exec rm '{}' \;

Misc

find . -name "rc.conf" -print
find . -name "rc.conf" -exec chmod o+r '{}' \;
find /usr/src -not \( -name "*,v" -o -name ".*,v" \) '{}' \; -print
find . -exec grep "bob and alice" '{}' \; -print
find . -exec grep -q "bob and alice" '{}' \; -print
find /path/ \( -name "foo*" -or -name "bar*" \) -type f -ls

See also

External links