find
can search for files/dirs in a dir hierarchy, based on various criteria such as name, type, size, time modified, ownership, ...
find PATH [OPTIONS] [EXPRESSIONS]
-name PATTERN
: specify the name of the file/directory you want to search.
Note: dot . not represent a single character in this pattern?
Note 2: indeed, turns out:
?
can match any single character except/
.*
can match any string of characters not containing/
(includes matching an empty string)**
can match any string of characters. This includes matching an empty string, and/
character. So it recurses into subdirectories.
-type [dfl]
: specify the type of the file, there are many types but you only need to remember:
d
: directoryf
: regular filel
: symbolic link
-size
: Files that match a specific size. E.g. -size +10M
will find all files that are larger than 10MB, vice versa with -size -10M
with the one that are smaller than 10MB.
-mtime
: Files that have been modified within a specific time frame. E.g. -mtime -7
will find all files that have been modified within the last 7 days. +7
for more than 7 days.
-user
: Files that are owned by a specific user. E.g. -user hacki
-exec
: Executes a command on each file that is found. E.g. -exec ls -l {} \;
will list the long format details of each file that is found.
Note: You could also use pipeline
*Note 2: EXTREMELY IMPORTANT, if you by and chance, use {}
inside command substitution (e.g. -exec echo "$(dirname {})" \;
), you must always remember that command substitution happens BEFORE the replacement of {}
, so the command is running dirname {}
instead of dirname <smt>
, results in error.
-perm
: Files that have been set permissions by User, Group or Others. e.g -perm /o+w
means anyone with write permission, -perm /u-x
means users without execute permission.
Using operators:
!
(-not
)-a
(-and
)-o
(-or
),
E.g.
find . -name "*.sh" -a -name "*.fish"
find . -path ./logs -prune -o -type f
*Note: the -not operator only applies to ONE option, use grouping \(
and \)
to encapsulate multiple option into one.
find . -maxdepth 1 \( -not -name ".config" -type d \) -o -name "*.sh" -type f
: find all script files with extension "sh" and excludes .config
directory.
find . -maxdepth 1 -not \( -name "*" -type d \) -o -name "*.sh" type f
: find all script files with extension "sh" and all files that are not directory with any names (excludes all directories)
Use -printf FORMAT
option: by default, find
command will prnit the name of each file that it finds
Use quotes ""
to prevent the shell from interpreting any special character, usually Space.
Use -maxdepth
option: search for a specific depth, avoid running too long.
Use -iname
instead of -name
option: case-insensitive search.
Use -prune
to tell find
to exclude a particular directory from the search.
E.g. to search all files in the current directory + its subdirectories, BUT, exclude the files in a directory named "logs"
find . -path ./logs -prune -o -type f -print
Here the -path
option is used to specify the directory you want to exclude, and -prune
tells find
to exclude the directory from the search.
-prune
option only works with directories. If you want exclude specific files from the search, use -not / !
operator with -name
option