Unix Find Tutorial
Dr. Nikolai Bezroukov
Version 5.00 (Nov 1, 2018)
- Introduction
- Find overview
-
In depth coverage (separate pages used)
-
Summary
-
Webliography
The idea behind find is extremely simple: this is a utility for searching files using
the directory information. Despite simplicity of the idea, Unix find is a complex
utility with its own mini language. Its behaviour is not intuitive and in complex cases it often fools even experienced UNIX professionals.
Find is useful not only as search instrument, but also can enhance functionality of those Unix utilities
that do not include tree traversal. For example few know that GNU grep has -r
option for that can be used to perform simple tree traversal tasks, for example grep
-r "search string" /tmp.). But you can always use find with grep to achieve the
same purpose with more flexibility.
There are several versions of find with the main two being POSIX find used in Solaris,
AIX, and HP-UX and GNU find used in linux. GNU find was written by Written by Eric B. Decker,
James Youngman, and Kevin Dalley. Version 4.5 or later is recommended. For full path Perl-style regular
expressions are supported (via option -regex). for file name you can use only either
AWK regex or
egrep regex. GNU find can also be used with
Windows as it is a part of Cygwin package.
Utility find should theoretically understands several types of regular expression with the most important being
basic (default) and extended regex (the same as used in egrep). The desired type of regex can
be specified with the option -regextype . Currently it implements five types of
regex. But do not worry: as of November 2018, in versions of Linux that I tested (6.5-6.10 and 7.3-7.5) this option does not
work, so you are confined to basic regex ;-):
- posix-basic -- This is the default (and the only one that currently
works). Metacharacter ? is one arbitrary
letter, and dot is the symbol dot not a metacharacter (NOTE: find man page tells us that the default is
Emacs Regex, but this is not true in most versions of Linux)
- posix-extended -- the only other implemented type of regex that makes sense
- posix-awk -- makes sense only for sysadmins with very good knowledge of AWK.
Basically identical to posix-extended
- posix-egrep -- basically identical to
posix-extended
- emacs See
EmacsWiki Regexp References. Man page incorrectly states that this is the default. This is not true as Emacs regex are a
flavor of extended regex, not basic regex.
GNU find can (and probably should) be installed on Solaris, HP-UX and AIX and used instead of POSIX
find, as it is more powerful, more flexible implementation that native find implementations. Pre-compiled by vendor version
of GNU find are available on
each of those three platforms. For sysadmin it is better to have a good knowledge of one utility then a mediocre
knowledge of two similar, but with many subtle differences in implementations of find (as always, devil is in details).
The popularity of find is related to the fact that it can do more then a simple tree traversal
available with option -r (and/or -R) in many Unix utilities. Unix also maintains a database of files used in locate
utility, but the capabilities of locate are tiny in comparison with capabilities of find queries. Find is especially useful for finding "lost"
or "misplaced" files" in the filesystem as well as for mass
operation with files meeting certain criteria (name, age, size, permission, etc) like deletion, changing of attributes, backup, and transmission to other servers,
or other filesystems, or parts of
the local filesystem.
The utility find traverses the specified filesystem and all mounted on it filesystems (unless option -xdev is
specified, which blocks this behaviors). symlinks by default are not followed (can be changed with option -L). For each file
the specified query ais applied and if the results is trur some actions can be performed. Evaluation of predicates in
find logical expression (also called search expression or query) is done in shortcut "AND" fashion: as soon as a
predicate fails no other are evaluated. So proper order of predicated in the queries can increase the efficiency of processing.
The traversal of directory
tree provided by find is very flexible. You can excluded deeply nest tree branches using -maxdepth predicate,
block entering mounted filesystems. Traversal also can be limited to specific types of filesystem. Those
capabilities are far superior to primitive built-in tree traversal (recursive option) that most Unix utilities provide. In this sense,
find is a nice example of Unix component philosophy. It not only performs the main function it was designed
for, but can serve as an enhancer of functionally of other utilities including utilities that do not
have built-in capability to traverse the directory tree.
From the point of view of computer science find is an interpreter of its own language for specifying queries, which is pretty flexible
and powerful, but is highly idiosyncratic -- it is used only in find. The language statement consists of multiple
predicates by default connected via implicit logical AND. This implicit order of evaluation can be modified using round
brackets and by using OR instead of AND for linking two ro more predicates like in classic Boolean logical expressions.
Negation is also supported. For historical reasons find mini-language is completely different from all other
UNIX commands: it uses full-word options rather than single-letter options. For example, instead of
a typical Unix-style option -f to specify filenames (like in tar -xvf mytar.tar)
find uses option -name.
Each predicate iether checks for specific condition (in this case it returns
true of false for each file checked), or perform specific action on file that already "passed" previous conditions (in this case it
is always returns true). While essentially any find query is a logical expression, we can also can view it as a pipeline, when
each check serves as a filter and cuts file that do no satisfy specified by it criteria.
This is a unique case of Unix utility in which you specify not a set of options, but a query in an application-specific language
on the command line.
Unlike the typical situation with options, the order of components of this query (called predicates) is important.
Using "find application specific language you can create complex logical expressions describing the qualities of the files. By default
they are connected with AND, but if needed you can also specify set of expressions connected by OR logical operation.
Some predicates are, in essence, more like regular Unix utilities options which change the overall behavior of find (for example, option mount
prohibits following mound points in filesystem traversal); it does not ake any sense to specify it in any other place other
the first, as it applied to the whole query.
By default find executes the action -print at the end sending the
result to STDIN. So even in action -print is not specified at the end of the the query, in the absence of other actions it
is added automatically at the end. There are several "replacement actions" like -ls or -exec .
While file can's accept
stdin as input stream -- it generated input steam internally by traversing the filesystem, it can pass it s output to the pipe.
In this sense it can be called "semi-filter". And in this role it is widely used as the first stage in pipes.
With the advent of scripting languages this idiosyncratic mini-language
for specifying queries probably outlived its usefulness, but nobody has courage to enhance find adding
a standard scripting language as a macro language: find is way too entrenched in Unix to be
easily replaced with something better.
Moreover, Unix still does not has a standard macrolanguage similar to Visual Basic in Windows, so, for example,
adding Lua as a macrolanguage might be a bad idea, if it popularity
might wane in the next decade, and other similar language became dominant. such a language can be enforced on the
community iether via POSIX, or ir should be supported by some important player (now there are two such players -- IBM and
Google ;-). At one time Sun played with the idea of using TCL as such a universal
macrolanguage in Solaris, but it became distracted by Java and the idea died. Another attempt in the same direction was
GNU Guile created by FSF as alternative to TCL, which was hated by Stallman.
Guile also flopped. Which was a very sad development. TCL or Guile or LUA adoption as a standard macrolanguage would improved
Unix ecosystem dramatically. Linux does not even reached the level which mainframes reaches with REXX many many years ago, so
in a sense it is a backward OS. But we digress...
The first argument for find is the directory to search (search root in find terminology).
It important to understand that search root can consist of multiple directories, for
example:
find /usr /bin /sbin /usr/bin /usr/sbin /opt -name sar # No /proc /tmp /var
In the example above we exclude non-relevant directories from the list of second level Unix directories
that contain binaries. You can do something like that programmatically
find `ls -d /[ubso]*` -name sar # No /proc /tmp /var
Search root can consist of multiple directories |
Searching for a binary that is not in the path is a frequent operation for most
sysadmins, so creating an alias or function for this purpose makes perfect sense. For example, a simple function
that allow n search executables can look like:
function ffind {
find /usr /bin /sbin /opt -name "$1*" -type f -ls
}
The list of directories to search can also be generated by script, for example
find `gen_root_dirs.sh` -type f -size 0 -ls # find files with zero size
Here we assume gen_root_dirs.sh returns the list of directories in which we need to perform
the search.
After the list of directories to search (search root) find expects so called "search
expression". In other words, the first argument starting with "-" is considered
to be a start of "search expression".
Search expression can be quite complex and contain several parts connected with -and (default) or -or
predicate. With occasional use of -not ('!') Each component of search expression is evaluated to true or false and if
resulting lofical expression is true then "action" options are executed. The defaul "action" option is to pront the name of the file
with the path to STDOUT there are other action components like -exec which have
side effects.
By default individual elements are assumed to be connected with AND predicate so all of them need
to be true to list the file in the results. For example to look across the /usr/local and
/var/www/html directory trees for filenames that contain the pattern "*.?htm*", you
can use the following command:
find /srv/www /var/html -name "*.?htm*" -type f
Please note that the order of components does matter, and
that you need quotes for any regex. Otherwise *htm* it will be evaluated immediately
in the context of the current directory by shell. Find can use several types of regular expressions. Default is basic regex or DOS-style regex, if you wish;
actually find uses as default emacs regex which is very close but not identical (for example allowing alteration with '|'), but we
will not delve in subtle differences between the two. See
EmacsWiki Regular Expression for details.
It is difficult to remember all the details of this language unless you construct complex queries
each day and that's why this page was created. Sometimes errors and miscalculations in constructing
find search expression lead to real disasters. That typically happens when find is
used to execute commands like rm, chown, chmod (via -exec option,
see below). You can wipe substantial part of directory
tree or change attributes of system files, if you are not careful. The key for preventing such disasters
is to test complex find search expression and see the list of file affected before running it with
rm, chown, chmod specified in -exec option.
So the first rule of using find is never execute complex query against the filesystem with
-exec option. First use -ls option to see what files will be picked up and only then
convert it into -exec. Of course in a hurry and under pressure all rules go down the toilet,
but still it make sense to remember this simple rule. Please read
Typical Errors in using find. It might help you
to avoid some of the most nasty errors.
Never try to execute complex find query with -exec
option without first testing the result by replacing -exec option with -ls
option. Please read
Typical Errors in using find. It might help
you to avoid some of the most nasty errors. |
Along with this page it make sense to consult the list of typical (and not so typical) examples which
can be found in in Examples page on this site as well
as in the links listed in Webliography.
An excellent paper
Advanced
techniques for using the UNIX find command was written by Bill Zimmerly. I highly recommend
to read it and print for the reference. Several examples in this tutorial are borrowed from the article.
The full search expression language contains several dozens of different predicates and options.
There are two versions of this language:
- Version implemented in POSIX find
- Version implemented in GNU find which is a superset of POSIX find.
GNU find is preferable and can make a difference in complex scripts. But for interactive use the
differences is minor: only small subset of options is typically used on day-to-day basis by system administrators.
Among them:
- -name True if pattern matches the current file
name. Simple regex (shell patterns) may be used. it should be in quotes to prevent shell expansion.
A backslash (\) is used as an escape character within the pattern. The pattern should be escaped
or quoted. If you need to include parts of the path in the pattern in GNU find you should
use predicate -wholename If you need to use regular
expressions you need to use predicates regextype and regex
(only GNU find)
Use the -iname predicate (only GNU find supports it)
to run a case-insensitive search, rather than just
-name. For example:
find . -follow -iname '*.htm' -print0 | xargs -i -0 mv '{}' ~/webhome
Usage of -print0 is an insurance for the correct processing of files with spaces.
- -fstype type True if the filesystem to which
the file belongs is of type type. For example on Solaris
mounted local filesystems have type ufs (Solaris 10 added zfs). For AIX local
filesystems are typically jfs2 (journaled file system). If you want to traverse NFS filesystems
you can use nfs (network file system). If you want to avoid traversing network and special
filesystems you should use predicate local and in certain circumstances predicate mount
- "-atime/-ctime/-mtime" [+|-]n
Each of those specifies selection of the files based on three Unix timestamps:
the last time a files's "access time", "file status" and "modification time".
Here n is time interval -- an integer with optional sign. It is
measured in 24-hour periods (days) or minutes (GNU find only) counted from the current
moment. Period can be used without sign or with plus of minus sign. The meaning of those three possibilities
are as following:
- n -- exactly n 24-hour periods (days) ago, 0 means today.
- +n -- "more then n 24-hour periods (days) ago", or older then n,
- -n -- less than n 24-hour periods (days) ago (-n), or younger then n.
It's evident that -1, and 0 are the same and both means "today".
Note: Gnu find provides the ability to use minutes as a unit instead of hours, for
example if you want to find what was changed during the installation of particular package
you can try (assuming that installation took 3 min):
find / -mmin -3 |
Examples
- Find everything in your home directory modified in the last 24 hours:
find $HOME -mtime -1
- Find everything in your home directory modified in the last 30 min
find $HOME -mmin -30
- Find files in your home directory that were NOT been modified a year or more:
find $HOME -mtime +365
- To find html files that have been modified in the last seven 24-hour periods (days),
you can use -mtime with the argument -7 (note the hyphen):
find . -mtime -7 -name "*.html"
If you use the number (without a hyphen), find will match only html files that were
modified exactly the specified number of days (24-hour period) ago. For example:
find . -mtime 1 -name "*.html" -print
- -newer/-anewer/-cnewer baseline_file The time of modification, access time
or creation time are compared with the same timestamp in the baseline file. If file is
a symbolic link and the -H option or the -L option is in effect, the modification
time of the file it points to is always used.
- -delete Delete files or directories; true if removal succeeded. If the removal
failed, an error message is issued. As deleted files are difficult to recover, you are strongly
advised to test the command substituting it first with -ls first, especially
if you are trying to delete files from system or other directories. Five minutes testing often saves
five hours frantic recovery effort ;-).
Five minutes testing often saves five hours frantic recovery effort
;-) |
This option also can be used for deleting files with "strange" characters in names. First, determine
the file or directory's inode. For example
ls -lhi *.html
Then use the find command with the inode of the troublemaker, for example:
find . -type f -inum 31467125 -exec mv {} new_name.html \;
To simply delete such a file you can use option -delete of GNU find:
find . -type f -inum 314167125 -delete
The same trick can be used for renaming files with special characters in names. See
How to rename files with special
characters in names.
- -exec command Executes the specified command
for each file found. This is the most powerful (and thus the most dangerous) option that find
provides. This option is more suitable for executing relatively simple commands. {} species
the current file which is expanded to a relative path starting with the name of one of the starting
directories, rather than just the basename of the matched file. You can use several instances of
{} in the command: GNU find replaces {} wherever it appears. For
more complex things post processing of output of find command with xargs is a safer
option as you can check the output first before running some potentially irreversible action on
those files. For examples and mode detailed coverage see
Using -exec option with find
- -local True if the file system type is not a remote file system
type. In Solaris those types are defined in the /etc/dfs/fstypes
file. nfs is used as the default remote filesystem type if the /etc/dfs/fstypes
file is not present. The -local option skips the hierarchy of non-local directories. You
can also search without descending more then certain number of levels as explained later or exclude
some directories from the search using
- -mount Always true. Restricts the search to the file system containing the directory
specified. Does not traverse mount points to other file systems.
-
-xdev Same as the -mount primary. Always evaluates to the value True. Prevents
the find command from traversing a file system different from the the set of directories
specified by the PATH.
- -xattr True if the file has extended attributes.
- -wholename simple-regex
[GNU find only] . File name matches simple regular expression (often called shell patterns).
In simple regular expressions the metacharacters '/' and '.' do not exist; so,
for example, you can specify:
find . -wholename '/lib*'
which will print entries from directories /lib64 and /lib.
To ignore the directories specified, use option -prune
For example, to skip the directory /proc and all files and directories under it
(which is important for linux as otherwise errors are produced you can something like this:find . -wholename '/proc/*' -prune -o -name file_to_be_found
If you administer a lot of linux boxes it is better to create function like:
function fff {
if [[ `uname` == "Linux" ]] ; do
alias fff='find . -wholename '/proc/*' -prune -o -name '
else
fff='find . -name ' # non GNUfinddoes not support -wholename
fi
}
Other useful options of the find command include:
- -regex regex [GNU find only] File full pathname matches regular expression.
This is a match on the whole pathname not just a filename. Predicate "-iregex"
option provides the capability to ignore case.
- -perm permissions Locates files with certain permission settings. Often used
for finding world-writable files or SUID files. See separate page devoted
to the topic
- -user Locates files that have specified ownership. Option
-nouser locates files without ownership. For such files
no user in /etc/passwd corresponds to file's numeric
user ID (UID). such files are often created when tar of sip archive is transferred from other server
on which the account probably exists under a different UID)
- -group Locates files that are owned by specified group. Option -nogroup means
that no group corresponds to file's numeric group ID (GID) of the file. This is useful option for
server cleanup, as with time structure of the groups changes but some file remain in now defunct
groups. Also files and tar balls downloaded by root from other servers might have numeric groups
that have no match on the box.
- -size Locates files with specified size. -size attribute lets you specify
how big the files should be to match. You can specify your size in kilobytes and optionally also
use + or - to specify size greater than or less than specified argument.
For example:
find /home -name "*.txt" -size 100k
find /home -name "*.txt" -size +100k
find /home -name "*.txt" -size -100k
The first brings up files of exactly 100KB, the second only files greater than 100KB, and the
last only files less than 100KB.
- -ls list current file in ls -dils format on standard output.
- -type Locates a certain type of file. The most typical options for -type are
as following:
- d - Directory
- f - File
- l - Link
For example, to limit search to directories use can use the -type d specifier.
Here's one example:
find . -type d -print
As a syntax helper one can use a web form for generating search expression.
Unix find command helper. In no way that means that
you can skip testing, especially if you plan to use option -exec. Such web forms are purely
syntax helpers. It is testing (and only testing) that can reveal some nasty surprises in what you thought
is a perfectly correct search expression.
The most commonly used predicate in find is -name, which compares the name of the file (without path) with a string
or regex and returns true or false as a result of this comparison. If you want to evaluate regular expression against the whole path
you need to use the predicate -regex instead.
Theoretically the type of regex in find is user-definable and can be changed with the option -regextype. which allows file
types of regex:
- two "normal": posix-basic(the default), posix-extended (the one that we studied in grep )
- three "esoteric": emacs , posix-awk, posix-egrep
The problem is that in version of find that I tested this option does nothing, and the only type of regex find accepts is basic regex.
For example
find -regextype posix-extended /etc -name '^[a-z].*\.[0-9]+$'> # -- DOES NOT WORK. Should find all files in /etc
that start with the letter and have numeric suffix
If regular expression is specified, is should be enclosed in quotation marks to prevent the shell from expanding it before the
find command:
find /etc -name "*.conf"
The example above find will list names of all objects in the /etc directories (file, directories, symlinks, etc) that ends
with .conf. We probably do not need to list directories and symlinks, so we better add option -type to limit
search to just regular files. The -type f is the most common option used is find searches. The type can also
be b (block device), c (character device), d (directory), p (pipe), l (symbolic
link), or s (socket).
find / -name "*.conf" -type f
In this example the two predicates -name "*.conf" and -type f form a simple find expression.
As we already mentioned above, individual predicates in the expression
are connected with logical AND. They are evaluated from left to right. some predicates like -maxdepth affect the amount
of traverse files and should always be specified first.
So for a file to get to the end of the expression (were implicit -print predicate will be executed on file) a file should
meet both of these conditions: it should have suffix "conf" and be a regular file.
To reverse the condition you can use to prefix it with -not.
find / -name "*.conf" -not -type f
To specify -or condition you need to use round brackets
(as shell interprets round brackets as metasymbols too, they need to be escaped or put in quotes)
find /etc \( type f -or type l \)
Summarizing the predicate can be organized into:
- Chain of predicated connected with AND. You do not need to specify AND explicitly, but
if you wish to do so you can, for example expr -and expr (or expr -a expr)
- Subexpression ( expr )-- Like in algebraic expressions all predicates in the subexpression are
evaluated first and the result of the expression is produced before the next predicate outside of this expression is evaluated.
Often used for several predicated connected by OR. (expr -or expr). Which also can be written as expr -o expr).
- Negation. -not expr (or ! expr)-- reverses the result of the predicate execution (true to
false and vise versa)
For example, to count the number of regular files and directories, do this:
[root@test01 etc]# find /etc -name "*.conf" '(' -type f -or -type d ')' | wc -l
The number of files without suffix .conf can be counted as well.
find . ! -name "*.conf" -type f | wc -l
Parentheses must be escaped by a backslash or quotes to prevent Bash from interpreting them as a subshell. Using parentheses, the
number of files ending in .txt or .sh can be expressed as
$ find . '(' -name "*.conf" -or -name '*.config' ')' -type f | wc -l
With so many files in the typical linux filesystem finding missing files is a regular pasture of sysadmins. Usually you
remember several facts about missing file. among them:
- min and max size of the file in question
- Time interval during which this file was last modified (or created, or accessed)
- Range of sized for the file (min and max)
- Particular phrase inside
There are
several predicates in find which can be to test files of iether the access (atime) or modification time(mtime), which
is the time a file was last read or written stored in the inode. There is also the third time stand called creation time ("ctime")
which actually is not attribute of the file but a directory in which file is listed and is nothing more then a date when the particular
record in the directory was created.
Fins provides reasonably flexible capabilities of specifying need time interval iether in days or minutes. Historically,
find times were measured in days (ctime, mtime) in connection with the other file ( -newer), but
the GNU version extended this capability provided options that allow specify the tike interval in hours (like -min switch).
find can look for files that were created or modified exactly in the specified interval, older then certain threshold,
or newer then certain threshold.
the most common are check for modified time. You can check the modified time, which is the time a file was last written to, by using
-newer, -mtime, and -mmin. The -newer switch checks to see whether one file was modified more recently
than a specified file. -mtime tests the number of days ago a file was accessed. -mmin allows to specified minutes
inread of days.
- To search for files modified N or less days ago include the minus sign before N. For example to find files
in /etc directory that were modified today use: find /etc -type f -mtime -1 -ls
- To search for files older than particular number of days, use plus sign followed by the number of days For example to find
files in /data directory older then one year (and this candidates for archiving or deletion) use: find /data -type f -mtime
+365 -ls
To find files that haven't been changed in more than one day:
find /etc -name "*.conf" -type f -mtime +0
- to search file that were created N day ago use number without any sign, for example to find files modified two days ago
use find /etc -type f -mtime 2 -ls
To find files that were modified the last hour:
[root@test01 etc]# find /etc -type f -mmin -60
/etc/sudoers
In other words, i a plus sign (+) precedes the amount of time, find searches for times greater than this amount. If a minus
sign (-) precedes the time measurement, find searches for times less than this amount. Likewise, -min -5 in
minutes means “younger than 5 minutes” or “zero to four minutes old”.
In addition to modification time can use the similar conditions with the creation time. The relevant options are -cnewer,
-ctime, and -cmin. The inode timestamp usually, but not always, represents the time the file was created.
Here are options we discussed for reference:
-amin n
File was last accessed n minutes ago.
-anewer file
File was last accessed more recently than file was modified. If file is a symbolic link and the -H option
or the -L option is in effect, the access time of the file it points to is always used.
-atime n
File was last accessed n*24 hours ago. When find figures out how many 24-hour periods ago the file was last accessed,
any fractional part is ignored, so to match -atime +1, a file has to have been accessed at least two days ago.
-cmin n
File's status was last changed n minutes ago.
-cnewer file
File's status was last changed more recently than file was modified. If file is a symbolic link and the -H
option or the -L option is in effect, the status-change time of the file it points to is always used.
-ctime n
File's status was last changed n*24 hours ago. See the comments for -atime to understand how rounding affects the
interpretation of file status change times.
-empty
File is empty and is either a regular file or a directory.
The -size predicate tests the size of a file. The default measurement is 512-byte blocks, which is counterintuitive to many
users and a common source of errors. Unlike the time-measurement predicates, which have different predicates for different measurements
of time, to change the unit of measurement for size you must follow the amount with a b (bytes), c (characters),
k (kilobytes), M (megabyte) G (gigabytes). Like the time measurements, the amount can have a minus sign (-) to test for
files smaller than the specified size, or a plus sign (+) to test for larger files.
For example, use this to find log files greater than 1GB:
$ find / -type f -size +1G
find shows the matching paths on standard output. Historically, the -print (whihc is the default and can
be omitted) or -ls predicates are used to specify format of output. There is also printf option (or action, to be more precise)
which allow to print selected attributes. Printing the paths is the default behavior. As sometime Unix servers often store files
from Microsoft Windows where using blanks in filenames are common there is also special option -print0 which allow pipes such
filenames to other utilities without automatic splitting them into parts.
- -follow
- Deprecated; use the -L option instead. Dereference symbolic links. Implies -noleaf. The -follow option
affects only those tests which appear after it on the command line. Unless the -H or -L option has been specified,
the position of the -follow option changes the behaviour of the -newer predicate; any files listed as the argument
of -newer will be dereferenced if they are symbolic links. The same consideration applies to -newerXY,
-anewer
and -cnewer. Similarly, the -type predicate will always match against the type of the file that a symbolic link
points to rather than the link itself. Using -follow causes the -lname and -ilname predicates always to return
false.
- -ignore_readdir_race
- Normally, find will emit an error message when it fails to stat a file. If you give this option and a file is deleted
between the time find reads the name of the file from the directory and the time it tries to stat the file, no error
message will be issued. This also applies to files or directories whose names are given on the command line. This option takes
effect at the time the command line is read, which means that you cannot search one part of the filesystem with this option
on and part of it with this option off (if you need to do that, you will need to issue two find commands instead, one
with the option and one without it).
- -maxdepth levels
- Descend at most levels (a non-negative integer) levels of directories below the command line arguments. -maxdepth
0 means only apply the tests and actions to the command line arguments.
- -mindepth levels
- Do not apply any tests or actions at levels less than levels (a non-negative integer). -mindepth 1 means
process all files except the command line arguments.
- -mount Don't descend directories on other filesystems. An alternate name for -xdev, for compatibility with some
other versions of find.
To perform an action on a successful match, use -exec. The -exec switch runs a program on each matching file and
have several modifications:
- -exec command ;
- Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments
to the command until an argument consisting of ';' is encountered. The string '{}' is replaced by the current file name
being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some
versions of find. Both of these constructions might need to be escaped (with a '\') or quoted to protect them from
expansion by the shell. See the EXAMPLES section for examples of the use of the -exec option. The specified
command is run once for each matched file. The command is executed in the starting directory. There are unavoidable security
problems surrounding use of the -exec action; you should use the -execdir option instead.
- -exec command {} +
- This variant of the -exec action runs the specified command on the selected files, but the command line is built
by appending each selected file name at the end; the total number of invocations of the command will be much less than the
number of matched files. The command line is built in much the same way that xargs builds its command lines. Only
one instance of '{}' is allowed within the command. The command is executed in the starting directory.
- -execdir command ;
- -execdir command {} +
- Like -exec, but the specified command is run from the subdirectory containing the matched file, which is not
normally the directory in which you started find. This a much more secure method for invoking commands, as it avoids
race conditions during resolution of the paths to the matched files. As with the -exec action, the '+' form of
-execdir will build a command line to process more than one matched file, but any given invocation of command
will only list files that exist in the same subdirectory. If you use this option, you must ensure that your $PATH
environment variable does not reference '.'; otherwise, an attacker can run any commands they like by leaving an appropriately-named
file in a directory in which you will run -execdir. The same applies to having entries in $PATH which are
empty or which are not absolute directory names.
- -ok command ;
- Like -exec but ask the user first. If the user agrees, run the command. Otherwise just return false.
If the command is run, its standard input is redirected from /dev/null.
- The response to the prompt is matched against a pair of regular expressions to determine if it is an affirmative
or negative response. This regular expression is obtained from the system if the 'POSIXLY_CORRECT' environment
variable is set, or otherwise from find's message translations. If the system has no suitable definition,
find's own definition will be used. In either case, the interpretation of the regular expression itself
will be affected by the environment variables 'LC_CTYPE' (character classes) and 'LC_COLLATE' (character ranges
and equivalence classes).
- -okdir command ;
- Like -execdir but ask the user first in the same way as for -ok. If the user does not agree,
just return false. If the command is run, its standard input is redirected from /dev/null.
As we already studied grep, we will use examples with grep, but it can be any utility or script.
Here is one simple example to find files with certain IP in /etc/hosts (note usage of option -H in grep):
$ find /etc -type f -name hosts -exec grep -H -10.10.10.10 {} \;
More than one action can be specified. To show the filename after a grep match, include -print.
$ find . -type f -name "*.txt" -exec grep Table {} \; -print
find expects {} to appear by itself (that is, surrounded by whitespace). It can't be combined with other characters,
such as in an attempt to form a new pathname. If this is necessary use wrapper script.
The -ok switch works the same way as -exec except that it asks for your condirmation whether the command should
run. you cna view it as a debug option.
$ find . -type f -name "*.txt" -ok rm {} \;
< rm ... ./orders.txt > ? n
< rm ... ./advocacy/linux.txt > ? n
< rm ... ./advocacy/old_orders.txt > ? n
The -ls action switch lists the matching files with more detail.
The -printf switch use set of macros which indicate what kind of information about the file to print:
- %a-- File's last access time in the format returned by the C ctime function.
- %c-- File's last status change time in the format returned by the C ctime function.
- %f-- File's name with any leading directories removed (only the last element).
- %g-- File's group name, or numeric group ID if the group has no name.
- %h-- Leading directories of file's name (all but the last element).
- %i-- File's inode number (in decimal).
- %m-- File's permission bits (in octal).
- %p-- File's pathname.
- %P-- File's pathname with the name of the command line argument under which it was found removed.
- %s-- File's size in bytes.
- %t-- File's last modification time in the format returned by the C ctime function.
- %u-- File's username, or numeric user ID if the user has no name.
The name xargs
, pronounced EX-args, means “combine arguments.” xargs
builds and executes command lines
by gathering together arguments it reads on the standard input. Most often, these arguments are lists of file names generated by
find
.
This an alterative to using option -exec. The later can dangerous if used directly (for example you can detect level two
directories in the deletion list and act accordingly), or it can be slow for a large number of files because the shell is invoked each
match, whle most utilities can accept a list of aginments. When you have the option of piping the results to a second command, the execution
speed is significantly faster than when using -exec. A pipe generates the results with two commands instead of hundreds or
thousands of commands.
Xargs also allows debugging.
Also some utilities does not accept the list of filenames from the standard input. for example grep is a filter and it treats standard
input as the stream to be analyzed, not as the list of files to be processed. Actually option --switch-stdio-to-filelist
for grep would be very useful.
Xargs allot to convert the list of files proficed by find in multiple argumnet for grep or other ustilities invocation. As
suhc is is much better, more modern solution to this problem.
The core functionality of xargs is convert STDIN into iterative calls to whatever program is specified. By default xargs is suppling
to each call as much filenames as OS system buffer allows, but you can epscify the exact number.
Let’s say that the output of find is a list of four files, one, two, three, and four. Using
xargs, these files could be given to searched by grep for particular lines much like with -exec option, but in single
grep invocation with four arguments, making processing more efficient and
find | xargs grep pattern
find /var/log -name "*.gz" -type f -size +0 -print | xargs gzip -xv
Reminder: -type f matches just plain files, and -size +0 matches files that aren’t zero bytes in size.
Tip
If you have spaces in filenames you need to use -print0 in find and then add an option -0 (zero) to
xargs:
find $HOME -name "html" -print0 | xargs -0 grep -i
For more information see xargs Command Tutorial
Prev | Contents |
Next
Society
Groupthink :
Two Party System
as Polyarchy :
Corruption of Regulators :
Bureaucracies :
Understanding Micromanagers
and Control Freaks : Toxic Managers :
Harvard Mafia :
Diplomatic Communication
: Surviving a Bad Performance
Review : Insufficient Retirement Funds as
Immanent Problem of Neoliberal Regime : PseudoScience :
Who Rules America :
Neoliberalism
: The Iron
Law of Oligarchy :
Libertarian Philosophy
Quotes
War and Peace
: Skeptical
Finance : John
Kenneth Galbraith :Talleyrand :
Oscar Wilde :
Otto Von Bismarck :
Keynes :
George Carlin :
Skeptics :
Propaganda : SE
quotes : Language Design and Programming Quotes :
Random IT-related quotes :
Somerset Maugham :
Marcus Aurelius :
Kurt Vonnegut :
Eric Hoffer :
Winston Churchill :
Napoleon Bonaparte :
Ambrose Bierce :
Bernard Shaw :
Mark Twain Quotes
Bulletin:
Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient
markets hypothesis :
Political Skeptic Bulletin, 2013 :
Unemployment Bulletin, 2010 :
Vol 23, No.10
(October, 2011) An observation about corporate security departments :
Slightly Skeptical Euromaydan Chronicles, June 2014 :
Greenspan legacy bulletin, 2008 :
Vol 25, No.10 (October, 2013) Cryptolocker Trojan
(Win32/Crilock.A) :
Vol 25, No.08 (August, 2013) Cloud providers
as intelligence collection hubs :
Financial Humor Bulletin, 2010 :
Inequality Bulletin, 2009 :
Financial Humor Bulletin, 2008 :
Copyleft Problems
Bulletin, 2004 :
Financial Humor Bulletin, 2011 :
Energy Bulletin, 2010 :
Malware Protection Bulletin, 2010 : Vol 26,
No.1 (January, 2013) Object-Oriented Cult :
Political Skeptic Bulletin, 2011 :
Vol 23, No.11 (November, 2011) Softpanorama classification
of sysadmin horror stories : Vol 25, No.05
(May, 2013) Corporate bullshit as a communication method :
Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law
History:
Fifty glorious years (1950-2000):
the triumph of the US computer engineering :
Donald Knuth : TAoCP
and its Influence of Computer Science : Richard Stallman
: Linus Torvalds :
Larry Wall :
John K. Ousterhout :
CTSS : Multix OS Unix
History : Unix shell history :
VI editor :
History of pipes concept :
Solaris : MS DOS
: Programming Languages History :
PL/1 : Simula 67 :
C :
History of GCC development :
Scripting Languages :
Perl history :
OS History : Mail :
DNS : SSH
: CPU Instruction Sets :
SPARC systems 1987-2006 :
Norton Commander :
Norton Utilities :
Norton Ghost :
Frontpage history :
Malware Defense History :
GNU Screen :
OSS early history
Classic books:
The Peter
Principle : Parkinson
Law : 1984 :
The Mythical Man-Month :
How to Solve It by George Polya :
The Art of Computer Programming :
The Elements of Programming Style :
The Unix Hater’s Handbook :
The Jargon file :
The True Believer :
Programming Pearls :
The Good Soldier Svejk :
The Power Elite
Most popular humor pages:
Manifest of the Softpanorama IT Slacker Society :
Ten Commandments
of the IT Slackers Society : Computer Humor Collection
: BSD Logo Story :
The Cuckoo's Egg :
IT Slang : C++ Humor
: ARE YOU A BBS ADDICT? :
The Perl Purity Test :
Object oriented programmers of all nations
: Financial Humor :
Financial Humor Bulletin,
2008 : Financial
Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related
Humor : Programming Language Humor :
Goldman Sachs related humor :
Greenspan humor : C Humor :
Scripting Humor :
Real Programmers Humor :
Web Humor : GPL-related Humor
: OFM Humor :
Politically Incorrect Humor :
IDS Humor :
"Linux Sucks" Humor : Russian
Musical Humor : Best Russian Programmer
Humor : Microsoft plans to buy Catholic Church
: Richard Stallman Related Humor :
Admin Humor : Perl-related
Humor : Linus Torvalds Related
humor : PseudoScience Related Humor :
Networking Humor :
Shell Humor :
Financial Humor Bulletin,
2011 : Financial
Humor Bulletin, 2012 :
Financial Humor Bulletin,
2013 : Java Humor : Software
Engineering Humor : Sun Solaris Related Humor :
Education Humor : IBM
Humor : Assembler-related Humor :
VIM Humor : Computer
Viruses Humor : Bright tomorrow is rescheduled
to a day after tomorrow : Classic Computer
Humor
The Last but not Least Technology is dominated by
two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt.
Ph.D
Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org
was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP)
without any remuneration. This document is an industrial compilation designed and created exclusively
for educational use and is distributed under the Softpanorama Content License.
Original materials copyright belong
to respective owners. Quotes are made for educational purposes only
in compliance with the fair use doctrine.
FAIR USE NOTICE This site contains
copyrighted material the use of which has not always been specifically
authorized by the copyright owner. We are making such material available
to advance understanding of computer science, IT technology, economic, scientific, and social
issues. We believe this constitutes a 'fair use' of any such
copyrighted material as provided by section 107 of the US Copyright Law according to which
such material can be distributed without profit exclusively for research and educational purposes.
This is a Spartan WHYFF (We Help You For Free)
site written by people for whom English is not a native language. Grammar and spelling errors should
be expected. The site contain some broken links as it develops like a living tree...
Disclaimer:
The statements, views and opinions presented on this web page are those of the author (or
referenced source) and are
not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness
of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be
tracked by Google please disable Javascript for this site. This site is perfectly usable without
Javascript.
Last modified:
July 28, 2019;
[an error occurred while processing this directive]