Linux find命令详解

一、find基本介绍与命令格式

1.find命令基本介绍
    find顾名思义就是查找,find命令主要沿着目录结构依次向下遍历,匹配符合条件的文件,可以附带执行相应的操作选项,默认的操作结果是打印出符合条件的文件与目录。如果使用该命令时,不设置任何参数,则 find 命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示

2.find命令基本信息:
命令名称:find
英文原意:search for files in a directory hierarchy.
所在路径:/bin/find
执行权限:所有用户
功能描述:在目录中查找文件

3.find命令格式
find 搜索路径 [选项] 搜索内容 [输出处理形式]

二、find命令参数

更多的用法可以通过man find命令去查看
1.关于Linux底下三种时间的简单介绍:
①atime

access time,显示的是文件中的数据最后被访问的时间,比如系统的进程直接使用或通过一些命令和脚本间接使用。(执行一些可执行文件或脚本)

②mtime

modify time,显示的是文件内容被修改的最后时间,比如用vim编辑时就会被改变。(也就是Block的内容)

③ctime

change time,显示的是文件的权限、拥有者、所属的组、链接数发生改变时的时间。当然当内容改变时也会随之改变(即inode内容发生改变和Block内容发生改变时)

2.参数表

参数描述
-name按文件名查找文件,文件名在参数后面
-iname根据文件名查找,不区分大小写
-perm按权限查找文件
-user按属主查找文件
-group按属组查找文件
-uid按用户uid查找文件
-gid按用户gid查找文件
-nouser查无有效属主的文件,即/etc/passwd文件中不存在该属主
-nogroup查无有效属组的文件,即/etc/group文件中不存在该属组
atime按文件访问时间查找文件,-n指n天以内,+n指n天以前,n是整数
-mtime按文件更改时间查找文件,-n指n天以内,+n指n天以前,n是整数
-ctime按文件属性改变时间查找文件,如文件的权限、属主、属组等,-n指n天以内,+n指n天以前,n是整数
-amin按文件访问时间查找文件,-n指n分钟以内,+n指n分钟以前,n是整数
-mmin按文件更改时间查找文件,-n指n分钟以内,+n指n分钟以前,n是整数
-cmin按文件属性改变时间查找文件,如文件的权限、属主、属组等,-n指n分钟以内,+n指n分钟以前,n是整数
-newer以文件更改时间作为范围查找文件,用法:-newer f1 !f2 表示查找文件更改时间比文件f1新,但比文件f2旧的文件
-type按文件类型查找文件,文件类型有f/d/l/b/c/p/s,分别是普通文件/目录/链接文件/块设备文件/字符设备文件/管道文件/套接字,socket文件
-size按文件大小查找文件,单位有cwbkMG,c:字节、w:字 (2字节)、b:代表 512 位元组的区块(如果用户没有指定后缀,则默认为 b)、k:表示 kilo bytes (1024字节)、M:兆字节(1048576字节)、G:千兆字节 (1073741824字节)
-depth在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找,当指定-delete行为时,会自动应用这个选项。
-fstype查位于某一类型文件系统中的文件,这些文件系统类型通常可 在/etc/fstab中找到
-mount查文件时不跨越文件系统mount点
-follow如果find命令查找遇到符号链接文件,就跟踪至链接所指向的文件
-cpio对匹配的文件使用cpio命令,将这些文件备份到磁带设备中
-path指定字符串作为寻找目录的范本样式
-prune使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用了- depth选项,那么-prune选项将被find命令忽略,由于-delete暗含-depth,因此无法有效地同时使用-prune和-delete
-empty搜索空文件或空目录
-maxdepth查找最大目录层数(最大深度),如:-maxdepth 1,即只查找一层目录
-mindepth查找最小目录层数(最小深度)

三、操作符

操作符号用来表示查找条件之间的逻辑关系

-and表示的是与关系,如果该操作符两边的查找条件为真,则条件成立,匹配文件。可以简写为-a。注意:如果多个查找条件之间没有使用操作符,则默认使用的是-and
-or表示的是或关系,如果该操作符两边的查找条件有任意一个为真,则条件成立,匹配文件。可以简写为-o
-not表示取反,如果操作符后面的查找条件为真,则反向匹配该查找条件,可以简写为!
()该操作符可以将查找条件与操作符组合起来形成更大的表达式。这用来控制逻辑计算的优先级。默认情况下,find命令按照从左到右的顺序执行,经常有必要重写默认执行顺序来得到想要的查询条件,即使没有必要使用圆括号的时候使用圆括号将查找条件包括起来对提高命令的可读性是很有帮助的。注意:因为圆括号字符对于shell来说有特殊的含义,所以在命令行使用的时候,需要用引号引起来才能作为实参传递给find命令。不过我们通常使用反斜杆(\)用来转义圆括号字符,需要注意的是,括号两边与括号内部u命令之间需要空格,'\(','\)'。可能直接文字描述我不好说清楚,你也不好理解,那么请看后面的实例吧

四、文件名通配符

按照本人理解,就是相当于shell基本正则
*:通配任意的字符,表示任何字符
?:表示任意单个字符
[]:示通配括号里面的任意一个字符,注意[]里面的内容会被解析成单个字符

五、输出处理形式

参数描述
-print将用find命令找到的文件输出到标准输出,格式为每列一个名称,每个名称之前皆有"./"字符串,如果查找出来的文件太多,建议使用此参数
-print0文件或目录名称列出到标准输出,格式为全部的名称皆在同一行
-printf将文件或目录名称列出到标准输出。格式可以自行指定,命令格式:-printf<输出格式>
-fprint此参数的效果和指定"-print"参数类似,但会把结果保存成指定的列表文件,命令格式:-fprint<列表文件>
-fprint0此参数的效果和指定"-print0"参数类似,但会把结果保存成指定的列表文件,命令格式:-fprint0<列表文件>
-fprintf此参数的效果和指定"-printf"参数类似,但会把结果保存成指定的列表文件,命令格式:-fprintf<列表文件><输出格式>
-ls对匹配的文件执行ls -dils命令,并且将结果发送到标准输出
-quit查找到一个立刻退出
-delete删除当前匹配的文件
-used查找文件或目录被更改之后在指定时间曾被存取过的文件或目录,单位以日计算,命令格式:-used <天数>
-exec对find命令所匹配到的文件执行该参数所给出的shell命令,命令格式为:-exec 命令 {} \;,注意大括号要与\保持空格,最后面是以;结尾
-ok和-exec的作用相同,不同的是-ok以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行,如果需要执行,用户输入y,然后回车即可
| xargs这里本来不想加入|的,但是xargs一般都是与|一起使用的,还是加上吧。。。,与-exec作用相同 ,但是为什么有-exec了还要| xargs呢?原因是:①在使用 find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出 ②exec是要等find命令执行完成之后才对find执行完成的结果进行操作,然而很不幸的是当文件太多的时候会出现文件队列过长的提示,这是应为linux有个临时内存地址只保存128K的数据,我们有个服务器目录中有超量的文件例如1万份文件,,要对其进行分类,使用exec就不行,这时候就需要用到xargs ③管道实现的是将前面的stdout(标准输出)作为后面的stdin(标准输入),但是有些命令不接受管道的传递方式,最常见的就是ls命令。有些时候命令希望管道传递的是参数,但是直接用管道有时无法传递到命令的参数位,这时候需要xargs,xargs实现的是将管道传输过来的stdin进行处理然后传递到命令的参数位上。也就是说xargs完成了两个行为:处理管道传输过来的stdin;将处理后的传递到正确的位置上,而且xargs的作用不仅仅限于简单的stdin传递到命令的参数位,它还可以将stdin或者文件stdin分割成批,每个批中有很多分割片段,然后将这些片段按批交给xargs后面的命令进行处理,这也就是为什么xargs命令一般与管道连用的原因了

六、实例

实例1:按文件名查找

1.查找/etc/目录下文件名为passwd的文件
[root@test1 ~]#find /etc/ -name passwd -print
/etc/passwd
/etc/pam.d/passwd

2.查找/etc/目录下文件名以.conf文件结尾的文件
[root@test1 ~]#find /etc/ -name *.conf -print | more
/etc/ld.so.conf
/etc/vsftpd/vsftpd.conf
...省略后面的内容...

实例2:按权限查找

-perm 表示权限
-perm 444   # 查找文件权限为444的文件(精确查找,文件权限必须为444-perm -444  # "-"表示与关系,查找文件权限中u位有r权限,并且g位有r权限,并且o位有r权限的文件
-perm /444  # "/"表示或关系,查找文件权限中u位有r权限,或者g位有r权限,或者o位有r权限的文件
-perm /777  # 777=rwx rwx rwx 即9个条件中满足任意一个即可

1.查找/etc/目录下文件权限为444的文件
[root@test1 ~]#find /etc/ -perm 444 -print |xargs ls -l | more
-r--r--r--  1 root root      63 Jul  4  2017 /etc/ld.so.conf.d/kernel-3.10.0-514.26.2.el7.x86_64.conf
-r--r--r--. 1 root root      63 Nov 23  2016 /etc/ld.so.conf.d/kernel-3.10.0-514.el7.x86_64.conf
-r--r--r--  1 root root     531 Mar 25  2020 
...以下内容省略...

2.查找/etc/目录下文件权限为
[root@test1 ~]#find /etc/ -perm 755 -print |xargs ls -l | more
-rwxr-xr-x.   1 root root   618 Mar 18  2014 /etc/cron.daily/man-db.cron
-rwxr-xr-x    1 root root   409 Dec  7  2016 /etc/dhcp/dhclient.d/chrony.sh
-rwxr-xr-x    1 root root  2227 Apr 12  2017 /etc/dhcp/dhclient.d/ntp.sh
...以下内容省略...

3./mnt下文件权限包含404的文件的g位加w的权限
[root@test1 ~]#find /mnt -perm 404 -exec chmod g+w {} \;

实例3:按属主和属组查找

1.查找/mnt/目录下文件属主为ops的文件
[root@test1 ~]#find /mnt/ -user ops -print

2.查找/mnt/目录下文件属组为ops的文件
[root@test1 ~]#find /mnt/ -group ops -print 

3.查找/mnt/目录下文件的属主与属组都为ops的文件(逻辑关系默认为并且)
[root@test1 ~]#find /mnt/ -user ops -group ops -print
-a 表示并且()-and的简写,所以也可以这样写
[root@test1 ~]#find /mnt/ -user ops -a -group ops -print

4.查找/mnt/目录下文件的属主或属组为ops的文件
-o 表示或者,是-or的简写
[root@test1 ~]#find /mnt/ -user ops -o -group ops -print 

5.查找/mnt/目录下文件属主不是ops的文件
-not表示反向匹配,取反,可以简写为!
[root@test1 ~]#find /mnt/ -not -user ops -print

6.查找/mnt/目录下无有效属主的文件,即该文件的属主在/etc/passwd中不存在
[root@test1 ~]#find /mnt/ -nouser -print

7.查找/mnt/目录下无有效所属组的文件,即该文件所属的组在/etc/groups中不存在
[root@test1 ~]#find /mnt/ -nogroup -print

8.在整个系统中查找既没有属主又没有属组的文件(这样的文件通常是很危险的,作为系统工程师的我们应该及时清除掉)
[root@test1 ~]#find / -nouser -a -nogroup

实例4:按用户gid,uid查找文件
查看用户uid、gid
[root@test1 ~]#id ops
uid=1007(ops) gid=1007(ops) groups=1007(ops)

1.根据用户uid查找文件
[root@test1 ~]#find / -uid 1007 -print | more

2.根据用户gid查找文件
[root@test1 ~]#find / -gid 1007 -print | more

实例5:按时间查找文件(atime、mtime、ctime、amin、mmin、cmin,以文件更改时间作为范围)
我们可以使用stat命令来查看一个文件的时间信息
在这里插入图片描述

1.查找当前目录当天修改过的文件(列出了两种方法)
[root@test1 ~]#find ./ -mtime -1 -type f -print |xargs ls -l
[root@test1 ~]#find ./ -mtime -1 -type f -exec ls -l {} \;

2.查找当前目录当天修改过的文件并询问是否要显示
[root@test1 ~]#find ./ -mtime -1 -type f -ok ls -l {} \;

3./mnt/目录下查找更改时间在5日以前的文件并删除它们
[root@test1 ~]#find ./ -type f -mtime +5 -exec rm {} \;

4.删除在/mnt/目录下查找到的超过30天没有访问过文件并删除它们
[root@test1 ~]#find /mnt -atime  +30 –exec rm –rf  {} \; 
-atime、-ctime等的使用方法与mtime差不多,这里就不一一罗列了

实例6:按文件类型查找文件

f表示普通文件
[root@test1 ~]#find /dev -type f -print

d表示目录
[root@test1 ~]#find /dev -type d -print

l表示链接文件
[root@test1 ~]#find /dev -type l -print

b表示块设备文件
[root@test1 ~]#find /dev -type b -print

c表示字符设备文件
[root@test1 ~]#find /dev -type c -print

p表示管道文件
[root@test1 ~]#find /dev -type p -print

s表示套接字,socket文件
[root@test1 ~]#find /dev -type s -print

实例7:按文件大小查找文件
-size 20K    #查找大小为20K的文件
-size -20K   #-表示小于;查找比20K小的文件
-size +20k   #+表示大于;查看比20K大的文件

单位:
c:字节
w:字 (2字节)
b:代表 512 位元组的区块(如果用户没有指定后缀,则默认为 b)
k:表示 kilo bytes (1024字节)
M:兆字节(1048576字节)
G:千兆字节 (1073741824字节)

1.查找/mnt目录下文件大小为20k的文件
[root@test1 ~]#find /mnt/ -size 20k -print

2.查找/mnt目录下比20k小的文件
[root@test1 ~]#find /mnt/ -size -20k -print

3.查找/mnt目录下比20k大的文件
[root@test1 ~]#find /mnt/ -size +20k -print

实例8:按文件所在的深度(层次)查找
-maxdepth    #最大深度
-mindepth    #最小深度

1./开始,查找文件名为passwd的文件,查找两层目录
[root@test1 ~]#find / -maxdepth 2 -name passwd
/etc/passwd   

2./开始,查找文件名为passwd的文件,查找三层目录
[root@test1 ~]#find / -maxdepth 3 -name passwd
/usr/bin/passwd
/etc/passwd
/etc/pam.d/passwd

3./开始,查找文件名为passwd的文件,最少查找两层目录
[root@test1 ~]#find / -mindepth 2 -name passwd
/usr/bin/passwd
/root/svn_repository/conf/passwd
/etc/passwd
/etc/pam.d/passwd

4./开始,查找文件名为passwd的文件,最少查找三层目录
[root@test1 ~]#find / -mindepth 3 -name passwd
/usr/bin/passwd
/root/svn_repository/conf/passwd
/etc/pam.d/passwd

实例9:根据文件的新旧程度来查找文件

1.查找当前目录下比./tmp.txt新的文件
[root@test1 ~]#find ./ -newer "tmp.txt" -type f -print -ls | more

2.查找当前目录下比./tmp.txt旧的文件
[root@test1 ~]#find ./ ! -newer "tmp.txt" -type f -print -ls | more

3.查找比tmp.txt新,比temp.txt旧的文件
[root@test1 ~]#find ./ -newer 'tmp.txt' ! -newer 'temp.txt' -type f -print -ls | more

实例10:-path与-prune结合使用忽略目录查找
-path   #指定字符串作为寻找目录的范本样式
-prune   #使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用了- depth选项,那么-prune选项将被find命令忽略,由于-delete暗含-depth,因此无法有效地同时使用-prune和-delete

1.在当前目录下查找所有的普通文件
[root@test1 ~]#find ./ -type f -print

2.在当前目录下的temp目录下查找所有的普通文件
[root@test1 ~]#find ./ -path "./temp*" -type f -print

3.在当前目录下的temp目录下查找所有以.sh结尾的文件
[root@test1 ~]# find ./ -path "./temp*" -name "*.sh" -print

4.排除当前目录下的temp目录及子目录查找.txt后缀文件
[root@test1 ~]#find ./ -path "./temp" -a -prune -o -name "*.txt" -print
因为find命令如果不指定操作符,则默认为-a,所以上面的命名也可以这样写,效果一样
[root@test1 ~]#find ./ -path "./temp" -prune -o -name "*.txt" -print

命令说明:
-a是and的缩写,意思是逻辑运算符"与关系"(&&)-o是-or的缩写,意思是逻辑运算符"或关系"(||)-not表示非关系

简单介绍一下逻辑运算符&&||:
  &&:只有在&& 左边的命令返回真的情况下,&& 右边的命令才会被执行。只要有一个命令为假,后面的命令都不会执行
  ||:有点不同于常规语法的“或“的功能,它是表示:只有在 || 左边的命令返回假,|| 右边的命令才会被执行。但是,只要有一个命令返回真,后面的命令就不会被执行,即:一直会运行到返回为真的命令时才会停止执行

整条命令的逻辑分析:
-path "./temp"属于测试条件
  1.如果遇到路径不是./temp,那么(-path "./temp")返回值为假,则-prune参数不会执行,所以(-path "./temp" -prune)为假,那么-o参数后面的命令就会继续执行
  2.如果遇到的路径是./temp,那么(-path "./temp")返回值为真,则-prune参数会生效执行,所以(-path "./temp" -prune)为真,那么-o后面的操作是不会执行的,这就满足了排除./temp目录去查询
 
5.在temp目录及temp1目录及子目录下查找.txt后缀的文件
[root@test1 ~]#find ./ \( -path "./temp*" -o -path "./temp1*" \) -name "*.txt" -print
注意:圆括号()表示表达式的结合。即指示 shell 不对后面的字符作特殊解释,而留给 find 命令去解释其意义。由于命令行不能直接使用圆括号,所以需要用反斜杠'\'进行转义(即'\'转义字符使命令行认识圆括号)。同时注意'\(','\)'两边都需空格,也就是小括号与括号内命令之间需要空格

6.在除temp目录及temp1目录以外的目录下查找txt后缀文件
[root@test1 ~]#find ./ \( -path "./temp*" -o -path "./temp1*" \) -prune -o -name "*.txt" -print

7.查找在当前目录中,不以.txt结尾并且不在./svn_repository目录中的普通文件
[root@test1 ~]#find ./ \( -name "*.txt" -o -path ./svn_repository \)  -prune -o -type f  -print | more

8.查找在当前目录中,不以.txt结尾并且不在以_repository结尾的目录中的普通文件
[root@test1 ~]#find ./ \( -name "*.txt" -o -path "./*_repository" \)  -prune -o -type f  -print | more

9.查找当前目录,深度为1层,排除以.开头的所有文件
[root@test1 ~]#find ./ -maxdepth 1 -type f -name ".*" -prune -o -type f -print

其他使用

1.删除当前目录下的所有目录
[root@test1 ~]#find ./ -type d -delete

2.显示当前目录下所有目录和链接文件的详细信息
[root@test1 ~]#find ./ -type d -o -type l -ls

3.find命令格式化输出,查找当前目录以及主目录下所有以.txt结尾的文件,并且格式化输出最终只输出文件名,也不输出路径
几个常用的输出格式(想要知道更多可以使用man find命令查看):
%u: 文件属主
%g: 文件属组
%s: 文件大小
%f: 文件名,删除了文件名前面的路径,只输出文件名
%t: 以制表符分割
%d: 文件在目录树中的深度; 0表示文件是命令行参数
%p: 文件名
\n: 换行

[root@test1 ~]#find ./ -name "*.txt" -printf "%f\n"
README.txt
3.txt
1.txt
2.txt
7.txt
9.txt
8.txt

4.找出当前目录下所有空目录
[root@test1 ~]#find ./ -type d -empty

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值