find
is a very common Linux command, but we usually find more than just a look, there will be further operations, this is where exec
comes into play.
exec Explanation.
The -exec argument is followed by the command command, which is terminated with ; as the end mark, so the semicolon after this command is indispensable, considering that the semicolon will have different meanings in each system, so a backslash is added in front.
The {} brackets represent the name of the file found by the previous find.
When you use find, you can use exec with find as long as you write the operation you want in a file, which is very convenient. In some operating systems, the -exec option is only allowed for commands such as l s or ls -l. Most users use this option to find old files and delete them. It is recommended that before actually executing the rm command to delete files, it is best to look at them with the ls command to make sure they are the files to be deleted. exec option is followed by the command or script to be executed, then a pair of { }, a space and a ,, and finally a semicolon. In order to use the exec option, you must also use the print option. If you verify the find command, you will see that it only outputs the relative path and filename from the current path.
Example 1: The ls -l command is placed in the -exec option of the find command
Command:
find . -type f -exec ls -l {} \;
output:
[root@localhost test]# find . -type f -exec ls -1 {} \;
-rw-r--r-- 1 root root 127 10-28 16:51 . /log2014.log
-rw-r--r-- 1 root root 0 10-28 14:47 . /test4/log3-2.log
-rw-r--r-- 1 root root 0 10-28 14:47 . /test4/log3-3.log
-rw-r--r-- 1 root root 0 10-28 14:47 . /test4/log3-1.log
-rw-r--r-- 1 root root 33 10-28 16:54 . /log2013.log
-rw-r--r-- 1 root root 302108 11-03 06:19 . /log2012.log
-rw-r--r-- 1 root root 25 10-28 17:02 . /log.log
-rw-r--r-- 1 root root 37 10-28 17:07 . /log.txt
-rw-r--r-- 1 root root 0 10-28 14:47 . /test3/log3-2.log
-rw-r--r-- 1 root root 0 10-28 14:47 . /test3/log3-3.log
-rw-r--r-- 1 root root 0 10-28 14:47 . /test3/log3-1.log
[root@localhost test]#
Explanation:
In the above example, the find command matches all the common files in the current directory and lists them with the ls -l command in the -exec option.
Example 2: Find files in the directory that have changed more than n days ago and delete them
Command:
find . -type f -mtime +14 -exec rm {} \;
output:
[root@localhost test]# 11
Total 328
-rw-r--r-- 1 root root 302108 11-03 06:19 log2012.log
-rw-r--r-- 1 root root 33 10-28 16:54 log2013.log
-rw-r--r-- 1 root root 127 10-28 16:51 log2014.log
lrwxrwxrwx 1 root root 7 10-28 15:18 log_link.log -> log.log
-rw-r--r-- 1 root root 25 10-28 17:02 log.log
-rw-r--r-- 1 root root 37 10-28 17:07 log.txt
drwxr-xr-x 6 root root 4096 10-27 01:58 scf
drwxrwxrwx 2 root root 4096 10-28 14:47 test3
drwxrwxrwx 2 root root 4096 10-28 14:47 test4
[root@localhost test]# find . -type f -mtime +14 -exec rm {} \;
[root@localhost test]# 11
Total 312
-rw-r--r-- 1 root root 302108 11-03 06:19 log2012.log
lrwxrwxrwx 1 root root 7 10-28 15:18 log_link.log -> log.log
drwxr-xr-x 6 root root 4096 10-27 01:58 scf
drwxrwxrwx 2 root root 4096 11-12 19:32 test3
drwxrwxrwx 2 root root 4096 11-12 19:32 test4
[root@localhost test]#
Description.
Before deleting a file in any way in the shell, you should look at the appropriate file first, always with care! When using commands such as mv
or rm
, you can use the safe mode of the -exec
option. It will prompt you before operating on each matched file.
Example 3: Find files in a directory that have changed more than n days ago and delete them, prompting you before doing so
Command:
find . -name "*.log" -mtime +5 -ok rm {} \;
output:
[root@localhost test]# 11
Total 312
-rw-r--r-- 1 root root 302108 11-03 06:19 log2012.log
lrwxrwxrwx 1 root root 7 10-28 15:18 log_link.log -> log.log
drwxr-xr-x 6 root root 4096 10-27 01:58 scf
drwxrwxrwx 2 root root 4096 11-12 19:32 test3
drwxrwxrwx 2 root root 4096 11-12 19:32 test4
[root@localhost test]# find . -name "*.log" -mtime +5 -ok rm {} \;
< rm ... . /log_link.log > ? y
< rm ... . /log2012.log > ? n
[root@localhost test]# 11
Total 312
-rw-r--r-- 1 root root 302108 11-03 06:19 log2012.log
drwxr-xr-x 6 root root 4096 10-27 01:58 scf
drwxrwxrwx 2 root root 4096 11-12 19:32 test3
drwxrwxrwx 2 root root 4096 11-12 19:32 test4
[root@localhost test]#
Note.
In the above example, the find command finds all files in the current directory with filenames ending in. log and changed more than 5 days ago, and deletes them, except that it gives a prompt before deleting them. Press y to delete the file, and n not to delete it.
Example 4: Using the grep command in -exec
Command:
find /etc -name "passwd*" -exec grep "root" {} \;
output:
[root@localhost test]# find /etc -name "passwd*" -exec grep "root" {} \;
root❌0:0:root:/root:/bin/bash
root❌0:0:root:/root:/bin/bash
[root@localhost test]#
Description:
Any form of command can be used in the -exec option. In the above example we use the grep command. find first matches all files with the file name “passwd*”, such as passwd, passwd.old, passwd.bak, and then executes the grep command to see if there is a root user in these files.
Example 5: Find files to move to a specified directory
Command:
find . -name "*.log" -exec mv {} . \;
output:
[root@localhost test]# 11
Total 12
drwxr-xr-x 6 root root 4096 10-27 01:58 scf
drwxrwxr-x 2 root root 4096 11-12 22:49 test3
drwxrwxr-x 2 root root 4096 11-12 19:32 test4
[root@localhost test]# cd test3/
[root@localhost test3]# 11
Total 304
-rw-r--r-- 1 root root 302108 11-03 06:19 log2012.log
-rw-r--r-- 1 root root 61 11-12 22:44 log2013.log
-rw-r--r-- 1 root root 0 11-12 22:25 log2014.log
[root@localhost test3]# find . -name "*.log" -exec mv {} . \;
[root@localhost test3]# 11
Total 0
[root@localhost test3]# cd .
[root@localhost test]# 11
Total 316
-rw-r--r-- 1 root root 302108 11-03 06:19 log2012.log
-rw-r--r-- 1 root root 61 11-12 22:44 log2013.log
-rw-r--r-- 1 root root 0 11-12 22:25 log2014.log
drwxr-xr-x 6 root root 4096 10-27 01:58 scf
drwxrwxr-x 2 root root 4096 11-12 22:50 test3
drwxrwxr-x 2 root root 4096 11-12 19:32 test4
[root@localhost test]#
Example 6: Executing the cp command with the exec option
Command:
find . -name "*.log" -exec cp {} test3 \;
output:
[root@localhost test3]# 11
Total 0
[root@localhost test3]# cd .
[root@localhost test]# 11
Total 316
-rw-r--r-- 1 root root 302108 11-03 06:19 log2012.log
-rw-r--r-- 1 root root 61 11-12 22:44 log2013.log
-rw-r--r-- 1 root root 0 11-12 22:25 log2014.log
drwxr-xr-x 6 root root 4096 10-27 01:58 scf
drwxrwxr-x 2 root root 4096 11-12 22:50 test3
drwxrwxr-x 2 root root 4096 11-12 19:32 test4
[root@localhost test]# find . -name "*.log" -exec cp {} test3 \;
cp: ". /test3/log2014.log" and "test3/log2014.log" are the same file
cp: ". /test3/log2013.log" and "test3/log2013.log" are the same file
cp: ". /test3/log2012.log" and "test3/log2012.log" are the same file
[root@localhost test]# cd test3
[root@localhost test3]# 11
Total 304
-rw-r--r-- 1 root root 302108 11-12 22:54 log2012.log
-rw-r--r-- 1 root root 61 11-12 22:54 log2013.log
-rw-r--r-- 1 root root 0 11-12 22:54 log2014.log
[root@localhost test3]#
Reference: