Gentoo Development Guide
find -- Finding Files
The find utility can be used to search for and perform commands upon
groups of files matching a given set of criteria. The basic usage is
find path rules.
For portability purposes, always specify a path. Do not rely
upon find defaulting to the current working directory if no
path is provided.
Useful rules include:
| Rule | Effect | POSIX? |
-name "blah" |
Only find files named blah. The * and ?
wildcards may be used but should be quoted as in -name 'blah*'.
|
yes |
\! -name "blah" |
Only find files not named blah.
|
yes |
-type f |
Find only regular files, not directories. | yes |
-type d |
Find only directories. | yes |
-type l |
Find only symbolic links. | yes |
-user foo |
Find only files belonging to user foo. It is best to use
named users rather than numeric UIDs. In particular, root
may not be UID 0 on some systems.
|
yes |
-group foo |
Find only files belonging to group foo. It is best to use
named groups rather than numeric GIDs.
|
yes |
-maxdepth 3 |
Only descend 3 levels into subdirectories.
-maxdepth 1 will ignore all subdiretories of the specified path.
|
no, GNU and BSD |
-mindepth 2 |
Ignore the first 2 directory levels before a match occurs.
-mindepth 1 will process all files except the command line arguments.
|
no, GNU and BSD |
-exec foo '{}' |
Execute a command. {} is replaced by the name of the
current matched file. See examples below.
|
yes |
-execdir foo '{}' |
Same as -exec but runs the command from within the basedir
of the match.
|
no, GNU and BSD |
-delete |
Delete the match. | no, GNU and FBSD |
Note
EAPI>=5 assumes GNU find, so it is safe to use GNU extensions in ebuild context for those EAPIs.
By default, find will echo a list of matching files to the
standard output. This can be used in a while loop:
while read f ; do
einfo "Doing unholy things to ${f}"
done < <(find "${S}" -type f)
Or a for loop (for small numbers of files):
for f in $(find "${S}" -type f) ; do
einfo "Calling down holy vengance upon ${f}"
done
Warning
In both cases, files with weird characters or spaces in their names may cause serious problems.
As an alternative you can use the -exec argument. Be careful
with escaping to ensure that bash doesn't gobble up the special
characters:
find "${S}" -name '*.data' -exec mv '{}' "${S}/data/" \;
When -exec is terminated by a ; character
(needs escaping or quoting) then the command line is built separately
for every match.
If it is terminated by a + character then the command line is
built by appending each selected file name at the end.
The syntax below is useful if the command you want to run accepts multiple
arguments such as doins and is more efficient in that case:
find "${S}" -name '*.so*' -exec doexe '{}' +
Find also supports negative matches:
find "${S}/bundled-libs" \! -name 'libbass.so' -delete
This will delete all files in the "bundled-libs" folder except "libbass.so".
Make sure you always escape the ! character, so it's not
interpreted by the shell.
Warning
The -exec argument has security issues, because of
race conditions
(this is also true for find . -print0 | xargs ... constructs).
This should not be a problem in ebuild context, because directories
typically aren't writeable by random users. However you should
consider -execdir as an alternative approach which runs the
command from inside the basedir of the match (note that -execdir
is not POSIX, see the table).
See find-1 and IEEE1003.1-2004-find for further details and examples.