Overview
Sometimes you may need to find files with certain characteristics in the system (such as file permissions, file owner, file length, file type, etc.). There may be many reasons for this. Maybe it's for security reasons, or it's a general system administration task, or maybe it's just to find a file that's saved somewhere. find is a very effective tool that can traverse the current directory or even the entire file system to find certain files or directories.
Because find has such a powerful function, it also has many options, most of which are worth our time to understand. Even if the system contains a Network File System (NFS), the find command is also valid in the file system, as long as you have the corresponding permissions.
When running a very resource-consuming find command, many people tend to execute it in the background, because traversing a large file system may take a long time (here refers to a file system of more than 30G bytes) .
Usage of find command
find pathname -options [-print -exec -ok]
The general format of the find command is:
find [-H] [-L] [-P] [path...] [expression]
Among them, the three main options are '-H' '-L' '-P' It is used to handle symbolic links. '-H' means to only follow the symbolic links specified in the command line, '-L' means to follow all symbolic links, and '-P' is the default option, which means not to follow symbolic links.
For example, there is a symbolic link e1000 in my current directory, and now I want to find the source file whose last letter in the file name is a number, then
$ find -H . -name "*[0-9].c" -print
./2234.c
Writing like the above can only find the files that meet the requirements in the current directory, but not the files under e1000. So you can write:
$ find -H e1000 . -name "*[0-9].c" -print
or use the '-L' option
$ find -L . -name "*[0-9]. The [path...] part in the c" -print
format indicates that this directory is used as the root directory to search.
[expression] in the format is an expression. The most basic expressions are divided into three categories: setting items (options), test items (tests), and action items (actions). These three categories can be combined together through logical operators (operators) to form larger and more complex expressions. Mode. The setting items (such as -depth, -maxdepth, etc.) are specific to this search task, not just to a certain file. The setting items always return true; the test item (test) is different. It performs matching tests on a specific file. Such as -name, -num, -user, etc., return true or false; action item (action) performs some action on a certain file (the most common such as -print), returns true or false.
It is the richness of the [expression] part that makes find so powerful. This part is more complicated and will be explained later.
find command options
find command has many options or expressions, each option is preceded by a dash -. Let's first look at the main options of this command and then give some examples.
-name Search for files by file name.
-perm Find files based on file permissions.
-prune Use this option to prevent the find command from searching in the currently specified directory. If the -depth option is also used, the -prune option will be ignored by the find command.
-user Search files according to their owners.
-group Find files according to the group they belong to.
-mtime -n or +n searches for files based on their change time. -n indicates that the file was changed within n days from now, and +n indicates that the file was changed from n days ago. The find command also has -atime and -ctime options, but they are similar to the -mtime option, so we only introduce the -mtime option here.
-nogroup Find files that do not have a valid group to which they belong, that is, the group to which the file belongs does not exist in /etc/groups.
-nouser Find files without a valid owner, that is, the owner of the file does not exist in /etc/password.
-newer file1 ! file2 Find files whose change time is newer than file1 but older than file2.
-type Find files of a certain type, such as:
b - block device file.
d - Directory.
c - Character device file.
p - Pipe file.
l - Symbolic link file.
f - normal file.
-size n[c] Search for files with a file length of n blocks. When c is included, the file length is measured in bytes.
-depth When searching for files, first search for files in the current directory, and then search in its subdirectories.
-fstype Find files located in a certain type of file system. These file system types can usually be found in the configuration file /etc/fstab. This configuration file contains information about the file system in this system.
-mount does not cross the file system mount point when searching for files.
-follow If the find command encounters a symbolic link file, it will follow the file pointed to by the link.
-cpio Use the cpio command on matching files to back up these files to tape devices.
Use the name option
The file name option is the most commonly used option for the find command. This option is either used alone or together with other options. You can use a filename pattern to match files, remember to enclose the filename pattern in quotes.
No matter what the current path is, if you want to find a file with a file name matching *.txt in your root directory $HOME, use ~ as the pathname parameter, and the tilde ~ represents your $HOME directory.
$ find ~ -name "*.txt" -print
If you want to find all '*.txt' files in the current directory and subdirectories, you can use:
$ find . -name "*.txt" -print
To find files whose names begin with a capital letter in the current directory and subdirectories you want, you can use:
$ find . -name "[A-Z]*" -print
If you want to find files whose names start with h o s t in the /etc directory For files starting with:
$ find /etc -name "host*" -print
If you want to find a file in the current directory whose name starts with two lowercase letters, followed by two numbers, and finally * . t x t
file, the following command will return the file named ax37.txt:
$ find . -name "[a-z][a-z][0--9][0--9].txt" -print
Use the perm option
If you want to find files according to the file permission mode, you can use the -perm option. You may need to find files that all users have execute permissions on, or you may want to view the file permission types in a user's directory. When using this option, it is best to use octal notation for permissions. In order to find files with file permission bits 7 5 5 in the current directory, that is, files that the owner of the file can read, write, and execute, and other users can read and execute, you can use:
$ find . -perm 755 -print logical operation The logical operators in
find mainly include the following, in order from high to low priority:
(expr)
The parentheses have the highest priority, first evaluate the value in the parentheses
! expr
expresses expr The value of the expression is inverted
-not expr
Same as above, but POSIX does not support
expr1 expr2
without any operator, which is equivalent to adding and between the two, that is, the AND operation, both expressions are true before the whole value is returned true. The expr1 expression is evaluated first. If it is false, expr2 is not evaluated.
expr1 -a expr2
Same as above
expr1 -and expr2
Same as above, but POSIX does not support
expr1 -o expr2
means to OR the values of the two expressions expr1 and expr2. As long as one of the left and right values is true, the entire The expression is true. The expr1 expression is evaluated first. If it is true, expr2 is not evaluated.
expr1 -or expr2
Same as above, but POSIX does not support
expr1, expr2
comma expressions. Both expr1 and expr2 will be evaluated, but only the value of expr2 will be returned. The value of expr1 will be discarded
Use the prune option
-prune is an action item, which means that when the file is a directory file, do not enter this directory for search. To understand the -prune action, you must first understand the search rules of the find command (it can also be said that the algorithm of the find command).
The find command recursively traverses the specified directory tree, and executes the expressions in the find command for each file in sequence. The expressions are first combined according to logical operators, and then the expressions are evaluated from left to right. Take the following code as an example to explain
find PATHP1 OPT1 TEST1 ACT1 (TEST2 or TEST3) ACT2
1. Perform the overall settings of the find command according to the OPT1 setting item. If there is no -depth setting item, perform the following steps in sequence
2. Command File variable File = PATHP1
3. Perform TEST1 test on the File file. If the execution result is false, go to (8)
4. Perform ACT1 action on the File file. If the execution result is false, go to (8)
5. Perform ACT1 on the File file. The file is subjected to the TEST2 test. If the execution result is true, go to (7)
6. Perform the TEST3 test on the File file. If the execution result is false, go to (8)
7. Perform the ACT2 action on the File file. 8. If the File file It is a directory, and the -prune action has not been executed, then enter this directory
9. Is there any file in the current directory? If there is a file in sequence, let File point to this file, go to (3);
10. Judgment Whether the current directory is PATHP1, if so, the program exits; if not, return to the previous directory, go to (9)
Understanding the above process, it is not difficult to understand why the following code only outputs a '.'
$ find . -prune
.
Furthermore, there are two files larger than 4090 bytes in the current directory, and there is only one file larger than 4096 bytes, as follows:
$ find . -size +4090c -print
.
./a_book_of_c. chm
$ find . -size +4096c -print
./a_book_of_c.chm
So, replace the above two -print with -prune, what do these two commands output?
$ find . -size +4090c -prune
.
$ find . -size +4096c -prune
./a_book_of_c.chm
-prune is often used together with -path or -wholename to avoid a certain directory, common The form is:
$ find PATH (-path
$ find . -size +0c -wholename "*e*[0-9]*" -o ! /( -name "." -o -name "*phone" /) -prune -name "* .c" -user xixi -o -name "*phone"
If you want to ignore a certain directory when searching for files because you know that the file you are looking for does not exist in that directory, you can use the -prune option to indicate what needs to be ignored. Table of contents. Be careful when using the -prune option, because if you also use the -depth option, the -prune option will be ignored by the find command.
If you want to find files in the /apps directory but not the /apps/bin directory, you can use:
$ find /apps -name "/apps/bin" -prune -o -print
Use user and nouser Option
If you want to find files according to the file owner, you can give the corresponding user name. For example, to find a file whose owner is dave in the $HOME directory, you can use:
$ find ~ -user dave -print
To find a file whose owner is uucp in the /etc directory:
$ find /etc -user uucp -print
To find files whose owner account has been deleted, you can use the -nouser option. This will allow you to find files whose owners do not have a valid account in the /etc/password file. When using the -nouser option, you don't have to give a username; the find command
will do the work for you. For example, if you want to find all such files in the /home directory, you can use:
$ find /home -nouser -print
Use the group and nogroup options
Just like the user and nouser options, for the user group to which the file belongs, The find command also has the same options. To find files belonging to the accts user group in the /apps directory, you can use:
$ find /apps -group accts -print
To find all files that do not have a valid user group, you can use nogroup options. The find command below finds such a file from the root directory of the file system
$ fine / -nogroup -print
Finds files by change time
If you want to find files by change time, you can use the mtime option. If the system suddenly runs out of free space, it is very likely that the length of a certain file has grown rapidly during this period. In this case, you can use the mtime option to find such a file. Use the minus sign - to limit files that were changed within n days from now, and use the plus sign + to limit files that were changed to n days ago.
If you want to find files with a change time within 5 days in the system root directory, you can use:
$ find / -mtime -5 -print
To find files with a change time 3 days ago in the /var/adm directory, you can Use:
$ find /var/adm -mtime +3 -print
Use newer option
If you want to find all files whose change time is newer than a certain file but older than another file, you can use the -newer option. Its general form is:
newest_file_name ! oldest_file_name
where, ! is a logical NOT symbol. Here are two files that were changed about two days apart.
The find command given below can find files whose change time is newer than the file age.awk but older than the file belts.awk:
$find . -newer age.awk ! -newer belts.awk -exec ls -l {} ;
If you want to use this option of the find command to find files that were changed within two hours, unless there is an existing file whose change time happened to be two hours ago, there will be no file with which to compare the change time. To solve this problem, you can first create a file and set its date and timestamp to the desired time. This can be achieved using the touch command.
Suppose the current time is 2 3: 4 0, and you want to find files whose change time is within two hours. You can first create a file like this:
A file that meets the requirements has been created; Here we assume that today is May 4th, and the change time of this file is 21:40, which is exactly two hours earlier than now.
Now we can use the -newer option of the find command to find all files in the current directory that have been changed within two hours:
$ find . -newer dstamp -print
Use the type option
There are several types in Unix or Linux systems Different file types, we have already done this in the previous chapter. If you want to find all directories in the /etc directory, you can use:
$ find /etc -type d -print. In order to find all directories in the current directory except For all types of files outside the directory, you can use:
$ find . ! -type d -print
To find all symbolic link files in the /etc directory, you can use:
$ find /etc -type l -print
Use The size option
can search files according to their length. The file length referred to here can be measured in blocks or bytes. The expression form of file length measured in bytes is N c; the file length measured in blocks can only be expressed by numbers. Personally, I always use bytes, and when looking for files by file length, most people prefer to use this file length in bytes, rather than the number of blocks, unless You are looking at the size of the file system because it is easier to convert using blocks.
To find files with a file length greater than 1 M bytes in the current directory, you can use:
$ find . -size +1000000c -print
To find files with a length of exactly 1 0 0 bytes in the /home/apache directory For files, you can use:
$ find /home/apache -size 100c -print
To find files longer than 10 blocks in the current directory (one block is equal to 5 1 2 bytes), you can use:
$ find . -size +10 -print
Use the depth option
When using the find command, you may want to match all files first and then search in subdirectories. You can make the find command do this using the depth option. One reason for this is that when using the find command to back up a file system to tape, you want to back up all the files first, and then back up the files in the subdirectory.
In the example below, the find command starts at the root of the file system and looks for a file named CON.FILE.
It will match all files first and then search in subdirectories.
$ find / -name "CON.FILE" -depth -print
Use the mount option
To find files in the current file system (without entering other file systems), you can use the mount option of the find command.
In the following example, we start from the current directory to find files located in this file system whose file names end with X C:
$ find . -name "*. to back up files to or restore files from tape devices. You can use the find command to find files in the entire file system (more often in part of the file system), and then use the cpio command to back them up to tape. If you want to use the cpio command to back up files in the /etc/, /home/ and /apps directories, you can use the command given below, but remember that you are in the root directory of the file system:
$cd /
$find etc home apps -depth -print | cpio -ivcdC65536 -o /dev/rmt0
(In the above example, the command at the end of the first line tells the shell that the command has not ended yet, and the subsequent carriage return is ignored.)
Above In the example, you should notice the lack of / in the path, which is called a relative path. The reason why relative paths are used is because when restoring these files from tape, you can choose the path to restore the files. For example, you can restore these files to another directory first, perform certain operations on them, and then restore them to the original directory. If an absolute path is used during backup, such as /etc, then during recovery, you can only restore to the /etc directory and have no other choice. In the
example above, I told the find command to first go into the /etc directory, then the /home and /apps directories, match files in those directories first, and then match files in their subdirectories, all of which will be piped Passed to the cpio command for backup. By the way, in the above example, the cpio command uses the C65536 option. I could have used the B option, but this way the size of each block is only 5 1 2 bytes. After using the C65536 option, the block size becomes 64K bytes (65536/1024).
Use exec or ok to execute shell commands
After matching some files, you may want to perform certain operations on them, then you can use the -exec option.
In order to use the exec option, the print option must be used at the same time. If you verify the find command, you will find that the command only outputs the relative path and file name from the current path.
In order to use the ls -l command to list the matched files, you can put the ls -l command in the -exec option of the find command, for example:
In the above example, the find command matches all ordinary files in the current directory and lists them using the ls -l command with the -exec option.
In order to find files in the /logs directory that were changed more than 5 days ago and delete them, you can use:
$ find logs -type f -mtime +5 -exec rm {} ;
Remember, use any method in the shell Before deleting a file, you should check the corresponding file first, so be careful! Safe mode with the -exec option can be used when using commands such as mv or rm. It will prompt you before operating on each matching file. In the following example, the find command searches for all files in the current directory whose file names end with . LOG and whose modification time is more than 5 days ago, and deletes them, but gives a prompt before deleting them.
Press the y key to delete the file, press the n key not to delete it.
Any form of command can be used with -exec option. In the following example we use grep command. The find command first matches all files named "password*", such as password, password.old, password.bak, and then executes the grep command to see if there is a rounder user in these files.
$ find . -regex ".*/[0-9]*/.c" -print
./2234.c
Here -wholename and -path are related to the full path mentioned above.
-wholename and -path are both test items (test) and have the same functions. -path literally gives people the illusion that it only matches path names (or directory names). In fact, it can also match file names, so the name -wholename is more appropriate. Look at this example. There is a phone directory in the current directory. There is a file named puk.txt in the phone directory. Use -path:
$ find . -path '*phone/pu*'
./phone/puk.txt
Another thing to mention: the general format of using -path is: find [path...] -path pattern...
It means: on the path specified in the [path...] part, use pattern to match all The complete file name of the file; rather than looking for the file in a similar pattern directory.
Output format
If you don’t want to find the file you want and output the file name monotonously, you can use the -printf action item to output the format you want. Here are a few parameters of the -printf action:
%p Output file Name, including path name
%f Output file name, excluding path name
%m Output file permissions in octal format
%g Group to which the output file belongs
%h Directory name where the output file is located
%u Output file Owner name
...
For example:
$ find . -user xixi -printf "%m %p //n"
644 ./phone1/hello.c
644 ./0dfe.c
find and xargs
When using the -exec option of the find command to process the matched files, the find command will pass all the matched files to exec for execution. Unfortunately, some systems have limits on the length of commands that can be passed to exec, so that an overflow error will occur after the find command has been running for a few minutes. The error message is usually "Parameter column too long" or "Parameter column overflowed". This is where the
xargs command comes in, especially in conjunction with the find command. The find command passes the matched files to the xargs command, and the x a rg s command only fetches part of the files instead of all of them at a time, unlike the -exec option. This way it can process the first batch of files it gets, then the next batch, and so on. In some systems, using the -exec option will initiate a corresponding process to process each matched file, instead of executing all the matched files as parameters at once; in some cases, there will be too many processes and the system will There is a problem of performance degradation, so the efficiency is not high; while using the xargs command, there is only one process. In addition, when using the xargs command, whether to obtain all parameters at once or in batches, and the number of parameters obtained each time will be determined based on the options of the command and the corresponding number of adjustable parameters in the system kernel.
The following example searches for every ordinary file in the system, and then uses the xargs command to test which type of file they belong to: The following example searches for the memory information dump file (core dump) in the entire system, and then saves the result to / In the tmp/core.log file:
$ find . -name "core" -print | xargs echo "" >/tmp/core.log
The following example finds all users with read and write capabilities in the /apps/audit directory and execute permissions on the file, and revoke the corresponding write permissions:
$ find /apps/audit -perm -7 -print | xargs chmod o-w
In the following example, we use the gr e p command to search for device this in all ordinary files Word:
$ find / -type f -print | type f -print | xargs grep "DBO"
Note that in the above example, it is used to cancel the special meaning of * in the find command in the shell.