linux find命令详解

find是Linux 中强大的搜索命令,可以按照文件名、权限、大小、时间、属主属组等,在指定目录下快速查找所需要的文件。命令所在路径:/bin/find

find命令语法

语法:

find [ 指定目录 ] [ 寻找条件 ] [ 查完后执行的动作 ]
或者:
find path -option [ -print ] [ -exec -ok command ]   {} \;

常用选项

-name '字串':查找文件名匹配所给字串的所有文件,字串内可用通配符 *、?、[ ]。
-iname '字串':查找文件名匹配所给字串的所有文件,字串内可用通配符 *、?、[ ]。iname 会忽略大小写。
-lname '字串':查找文件名匹配所给字串的所有符号链接文件,字串内可用通配符 *、?、[ ]。
-gid n:查找用户组ID为 n 的所有文件。
-uid n:查找用户ID为 n 的所有文件。
-group '字串':查找属于用户组名为所给字串的所有的文件。
-user '字串':查找属于用户名为所给字串的所有的文件。
-empty:查找大小为 0的目录或文件。
-path '字串':查找路径名匹配所给字串的所有文件,字串内可用通配符*、?、[ ]。
-ipath '字串':ipath 会忽略大小写。
-perm 权限:查找具有指定权限的文件和目录,权限的表示可以如711,644。
-size [+-]n[bckw][MG]:查找指定文件大小的文件,n 后面的字符表示单位,缺省为 b,代表512字节的块。
-type x:查找类型为 x 的文件。

寻找条件

说明:find命令从指定的起始目录开始,递归地搜索其各个子目录,查找满足寻找条件的文件并对之采取相关的操作。 该命令提供的寻找条件可以是一个用逻辑运算符 notandor 组成的复合条件。

逻辑运算符 and、or、not 的具体含义如下:
(1)and:逻辑与,在命令中用-a表示,是系统缺省的选项,表示只有当所给的条件都满足时,寻找条件才算满足。
例如:

find ./ -name 'test.txt' -type c -user 'cavan'

该命令寻找三个给定条件都满足的所有文件,即名称为test.txt、文件类型为字符设备文件、用户为cavan的所有文件。
(2) or:逻辑或,在命令中用-o表示。该运算符表示只要所给的条件中有一个满足时,寻找条件就算满足。
例如:

find ./ -name 'test.txt' -o -name 'mina*'

该命令查询文件名为 test.txt 或是匹配 mina* 的所有文件。
(3) not:逻辑非,在命令中用 ! 表示。该运算符表示查找不满足所给条件的文件 。
例如:

find ./ ! -name 'test.txt'

该命令查询文件名不是 test.txt 的所有文件。
需要说明的是:当使用很多的逻辑选项时,可以用括号把这些选项括起来。为了避免 Shell本身对括号引起误解,在话号前需要加转义字符\来去除括号的意义。例:

find ./ \( -name 'tmp' -xtype c -user 'inin' \)

常用动作

-exec 命令名称 {}  对符合条件的文件执行所给的Linux 命令,而不询问用户是否需要执行该命令。{}表示命令的参数即为所找到的文件;命令的末尾必须以“ \;”结束。
-ok 命令名称 {}   对符合条件的文件执行所给的Linux 命令,与exec不同的是,它会询问用户是否需要执行该命令(很少使用)。
-ls    详细列出所找到的所有文件。
-fprintf 文件名 将找到的文件名写入指定文件。
-print   在标准输出设备上显示查找出的文件名。
-print0  可以处理文件名包含空格情况,建议find与xargs结合时使用。
-printf  格式 格式的写法请参考有关C语言的书。
-delete  将匹配到的文件删除

find查找实例

(1)按文件类型查找

find -type [ f| d| b| c| p| l ]:查找某一类型的文件。-xtype x 与 -type 基本相同,但只查找符号链接文件。

  • [d]:目录文件
  • [f]:普通文件
  • [l]:链接文件 (symbolic links)
  • [d]:设备
  • [b]:块设备文件
  • [c]:字符设备文件
  • [s]:套接字文件
  • [p]:管道文件 (FIFO)

例如:

#查找当前目录下所有的普通文件
find ./ -type f 

#查找当前目录下所有的目录
find ./ -type d 

#查找当前目录下所有非目录类型文件
find ./ ! -type d 

#查找当前目录下所有的符号链接
find ./ -type l 

#查找目录并列出目录下的文件(为找到的每一个目录单独执行ls命令,没有选项-print时文件列表前一行不会显示目录名称)
find ./ -type d -print -exec ls {} \; 

#查找目录并列出目录下的文件(为找到的每一个目录单独执行ls命令,执行命令前需要确认)
find ./ -type d -ok ls {} \; 

#查找目录并列出目录下的文件(将找到的目录添加到ls命令后一次执行,参数过长时会分多次执行)
find ./ -type d -exec ls {} + 

(2)按文件的更新时间查找

find -mtime [ n| -n| +n ]:按照文件的更改时间来查找文件,n表示天数。分别表示第n天、n天以内及n天以前。

  • -amin n:查找n分钟前被访问过的所有文件。
  • -atime n:查找n天前被访问过的所有文件。
  • -cmin n:查找n分钟前文件状态被修改过的所有文件。
  • -ctime n:查找n天前文件状态被修改过的所有文件。
  • -mmin n:查找n分钟前文件内容被修改过的所有文件。
  • -mtime n:查找n天以前文件内容被修改过的所有文件。
  • -cnewer file:比文件 file 更新的文件
  • -anewer file:比文件 file 更晚被读取过的文件
  • -newer file1 ! newer file2:查找更改时间比文件file1新但比文件file2旧的文件

访问时间戳(atime、amin):最后一次读取文件的时间。
修改时间戳 (mtime、mmin):文件内容最后一次被修改的时间。
更改时间戳 (ctime、cmin):上次更改文件元数据的时间(如,所有权、位置、文件类型和权限设置)

三个时间的区别,这里用 mtime 数据修改时间来举例,重点说说 "[+-]"时间的含义。
-5:代表5内修改的文件。
5:代表前5~6天那一天修改的文件。
+5:代表6天前修改的文件。

find ./ -type f -atime +365

# 如果我们需要查找 mtime 正好是 5 天前的文件,请不要包含 +,因为它的意思是“大于”。
find ./ -type f -mtime 5

# 显然,+ 表示“大于”,- 表示“小于”。所以我们可以搜索 ctime 在 5~10 天前的文件:
find ./ -type f -ctime +5 -ctime -10

(3)按文件名称查找

  • -name '字串':查找文件名匹配所给字串的所有文件,字串内可用通配符 *?[ ]
#查找当前目录下以.txt后缀的文件
find ./ -name "*.txt"  

#查找当前目录下以大写开头的文件
find ./ -name "[A-Z]*" 

#查找当前目录下以host开头的文件
find ./ -name "host*" 

#查找当前目录下txt和unl后缀的文件
find ./ -maxdepth 1 -type f -name "*.txt" -o -name "*.unl" 

#同上
find ./ -maxdepth 1 -type f ( -name "*.txt" -o -name "*.unl" ) 

(4)按文件大小查找

find -size 选项使我们能够按指定大小查找文件。
我们约定以下计量单位:

  • b:512 字节块(默认)
  • c:字节
  • w:双字节字
  • k:KB
  • M:MB
  • G:GB

类似于按时间戳查找文件,+ 表示“大于”,- 表示“小于”。例如,要查找大小为 10 MB ~ 1 GB 的文件:

#查找文件size小于10个字节的文件或目录
find ./ -size -10c  

#查找文件size等于10个字节的文件或目录
find ./ -size 10c  

#查找文件size大于10个字节的文件或目录
find ./ -size +10c  

#查找文件size小于10k的文件或目录
find ./ -size -10k  

#查找文件size小于10M的文件或目录
find ./ -size -10M  

#查找文件size小于10G的文件或目录
find ./ -size -10G  

#查找文件size大于10M和小于1G的文件
find ./ -type f -size +10M -size -1G   

(5)按文件权限查找

  • -perm:按执行权限来查找
  • -empty:查找长度为零(即空文件)的文件 r 4 w 2 x 1

例如:

# 查找权限为644的文件或目录(需完全符合)
find ./ -perm 664

# 查找用户/组权限为读写,其他用户权限为读(其他权限不限)的文件或目录
find ./ -perm -664

# 查找用户有写权限或者组用户有写权限的文件或目录
find ./ -perm /220
find ./ -perm /u+w,g+w
find ./ -perm /u=w,g=w

# 查找所有者权限有读权限的目录或文件
find ./ -perm -u=r

# 查找用户组权限有读权限的目录或文件
find ./ -perm -g=r

# 查找其它用户权限有读权限的目录或文件
find ./ -perm -o=r

# 查看当前目录以及子目录下其他用户可以读写可执行的目录或文件
find ./ -perm +0007 # 部分版本不支持,可采用find ./ -perm /0007代替

(6)按文件属主、属组查找

  • -uid 用户 ID:按照用户 ID 査找所有者是指定 ID 的文件
  • -gid 组 ID:按照用户组 ID 査找所属组是指定 ID 的文件
  • -user 用户名:按照用户名査找所有者是指定用户的文件
  • -group 组名:按照组名査找所属组是指定用户组的文件
  • -nouser:査找没有所有者的文件

例如:

#查找当前目录下属主为mysql的文件
find ./etc -user mysql  

#查找当前目录下属组为gname的文件
find ./etc -group gname  

#查找文件的用户ID不存在的文件
find ./ -nouser  

#查找文件的组ID不存在的文件
find ./ -nogroup  

#查找有执行权限但没有可读权限的文件
find ./ -executable \! -readable  

#查找有执行权限的文件
find ./ -executable -ls

find组合命令实例(xargs&exec)

例如:

find . -type f -name "*.sql" -exec dos2unix {} \;
find /home -mmin +5 -name "localhost_access_log.*.txt" -exec chmod 440 {} \;
find /home -name '*.log.*' \( \! -name '*.current' \) -exec chmod 440 {} \;
find /usr/local/tomcat -type f -name "*.xml"| xargs chmod 600
find /usr/local/tomcat -type f -name "*.jar"| xargs chmod 500
find /usr/local/tomcat -type f -name "*.tar.gz"| xargs chmod 600
find /usr/local/tomcat -type f -name "*.class"| xargs chmod 500
find /usr/local/tomcat -maxdepth 1 -type f | xargs chmod 600
find /home/cavan -type d | grep -v '^\./\.' | xargs chmod 750
find /home/cavan  -maxdepth 1 -type f | xargs chmod 640 

#查找/home目录下所有.txt文件并把他们拼接到all.txt文件中
find /home/ -type f -name "*.txt" -exec cat {} \;>all.txt 

#查找/home目录下所有.txt文件并把他们复制到/opt/backup文件中
find /home/ -type f -name "*.txt" -exec cp {} /opt/backup/ \;  

#查找当前目录 用户组是root的文件,并将其用户:用户组修改为cavan:cavan
find ./ -maxdepth 1 -type f -group root -exec chown cavan:cavan {} \;  

【注意】

  1. -exec 选项后面的命令必须以分号(;)结束。众所周知,转义字符用于去除单个字符的特殊含义。在 Linux 中,反斜杠 \ 用作转义字符。所以我们将它用于分号字符。
  2. -a 可省略,默认是且的关系
  3. 使用占位符{}来表示find到的文件名
  4. find命令中+\;有什么区别?
    -exec后会去执行一条命令,命令想要终止要加上终结符,+都可以作为终结符。
    其中会对每一个find到的文件去执行一次命令。而+让find到的文件一次性执行完命令。为什么必须有终结符?因为一个find后面可以有多个-exec,所以必须要有终结符分割他们。如果不加,会包缺少参数。
    详见:https://www.cjavapy.com/article/2035/
    详见例子:http://cn.voidcc.com/question/p-qmeicxae-rn.html
  5. -exec后为什么要加\?
    是shell的命令分隔符,如果只有,那么这条命令就会被shell截断
  6. 推荐使用-exec来执行其他操作,具体原因无。
  7. -print0: 可以处理文件名包含空格情况,建议find与xargs结合时使用。(注意空格文件场景,在安全章节会讲到find命令安全性)

参考:

http://t.zoukankan.com/linyfeng-p-6849949.html
https://blog.csdn.net/weixin_44519124/article/details/102542708

posted @ 2022-12-13 23:14  cavan丶keke  阅读(4245)  评论(0编辑  收藏  举报