文件查找工具locate和find的使用分析
不管是在windows系统中还是在Linux系统中,我们经常会一些文件进行搜索查找,而在Linux系统中经常用到的搜索工具有locate和find,这两种搜索工具的工具原理和用法都不相同,一下将这对这两种搜索工具的使用进行分析。
1、locate工具的工作原理是对/var/lib/mlocate/mlocat.db数据库进行文件搜索,而不是实时的在磁盘上搜索,因此它具有查找速度快的特点。mlocat.db数据库中包含所有本地文件信息,使用locate进行文件查找时主要依赖于其事先构建好的索引,其索引的构建是在系统较为空闲时周期性的自动进行,并且索引的构建过程需要遍历整个根文件系统,因此构建索引时的资源消耗比较大,由此可以发现locate还具有查找到的文件都是非实时文件的特点,也就是说locate查不到最近新变动过的文件,想要查找最新变动过的文件需要先使用updatedb命令手动更新数据库。locate还具有模糊查找的特点,可以理解为locate命令后面跟的不是文件名,而是关键字,关键字也可以使用文件通配符表示,只要符合关键字内容的文件都能被查找出来,另外locate搜索的不仅仅是文件名,而是全路径。
locate的用法:locate [OPTION]... [PATTERN]...
locate常用选项如下:
-i:忽略大小写
-n:只列出搜索到的前几行内容
-r:支持使用正则表达式
2、find工具的工作原理与locate不同,find是实时的针对磁盘进行文件搜索的,并且find是可以对指定目录进行精确查找的,因此find相对于locate来说查找速度较慢。find的功能非常强大,并且使用灵活。
find的用法:find [OPTION]... [查找路径] [查找条件] [处理动作]
查找路径:查找指定目录下的所有文件,默认递归查找,如指定查找用户家目录下的所有文件
查找条件:根据指定的条件进行文件查找,如根据日期查找、根据文件名进行精确查找、或根据文件所属用户进行查找等。
处理动作:是指将查找到的文件进行怎样的处理,如复制、删除等,默认是-print,即列出查找到的所有文件
下面将对find工具的具体使用进行分析:
查找路径
根据指定的路径进行文件查找,如果不指定路径,默认情况下查找当前路径下的所有文件
[root@liang ~]# find 或 [root@liang ~]# find ./ #两个命令的意思是一样的,都是查找当前目录下的所有文件 [root@liang ~]# find /etc/ #查找/etc/目录下的所有文件
注意:如果指定的目录是软链接,则指定该目录时一定要在后面加上斜线,否则查找的是文件而不是目录下的文件
[root@liang /]# ll /etc/init.d lrwxrwxrwx. 1 root root 11 6月 15 16:47 /etc/init.d -> rc.d/init.d [root@liang /]# find /etc/init.d /etc/init.d [root@liang /]# find /etc/init.d/ /etc/init.d/ /etc/init.d/rpcidmapd ...
查找条件
find命令的强大之处在于其查找条件有很多,可以根据不同的条件查找所需要的文件,并且使用非常灵活,下面将一一介绍不同的查找条件:
-name FILENAME:根据文件名精确查找文件,可以使用文件通配符
#查找当前目录下sshd文件 [root@liang testdir]# find -name sshd #查找/etc 目录下的passwd文件 [root@liang testdir]# find /etc -name passwd
-iname FILENAME:根据文件名精确查找文件,可以使用文件通配符,与-name不同的是不区分字母大小写-
-inum NUM:按磁盘上存储文件的inode号查找
[root@liang testdir]# find -inum 2490447
-samefile FILENAME:查找存储在磁盘上相同inode号的文件
#查找当前目录下与acpid相同inode号的文件 [root@liang testdir]# find -samefile acpid
-links NUM:查找软链接的链接数为NUM个的文件
#查找当前目录下连接数为10的所有文件 [root@fengl /]# find -links 10
-regex “PATTERN”:使用正则表达式查找,PATTERN匹配的是整个文件路径字符串,而不仅仅是文件名
#查找当前目录下所有以a或b开头的文件,注意正则表达式一定是匹配全路径的,当前目录下应加上“./” [root@liang testdir]# find -regex \./[ab].*
-user USERNAME:查找属主为指定用户(UID)的文件。
-uid UserID:根据用户UID进行查找
-group GROUPNAME:查找属组为指定组(GID)的文件
-gid GroupID:根据组的GID进行查找
-user与-uid其实都是根据用户UID进行文件查找的,如果两个用户的UID一样,则根据一个用户的用户名查找文件时会将其属主的文件都列出来,同理,-group和-gid也是一样的,其实都是根据组的GID进行文件查找的
#根据用户查找 [root@liang testdir]# find /home -user ggg -ls 1703938 4 drwx------ 3 liang liang 4096 8月 3 05:29 /home/liang 1703939 4 -rw-r--r-- 1 liang liang 124 5月 11 07:21 /home/liang/.bashrc 1703940 4 drwxr-xr-x 2 liang liang 4096 11月 12 2010 /home/liang/.gnome2 1703995 4 -rw------- 1 liang liang 297 8月 3 05:29 /home/liang/.bash_history 1703941 4 -rw-r--r-- 1 liang liang 176 5月 11 07:21 /home/liang/.bash_profile 1703942 4 -rw-r--r-- 1 liang liang 18 5月 11 07:21 /home/liang/.bash_logout 1704026 4 drwx------ 3 liang ggg 4096 8月 17 00:50 /home/ggg 1704027 4 -rw-r--r-- 1 liang ggg 124 5月 11 07:21 /home/ggg/.bashrc 1704028 4 drwxr-xr-x 2 liang ggg 4096 11月 12 2010 /home/ggg/.gnome2 1704029 4 -rw-r--r-- 1 liang ggg 176 5月 11 07:21 /home/ggg/.bash_profile 1704030 4 -rw-r--r-- 1 liang ggg 18 5月 11 07:21 /home/ggg/.bash_logout #根据UID查找 [root@liang testdir]# find /home -uid 500 -ls 1703938 4 drwx------ 3 liang liang 4096 8月 3 05:29 /home/liang 1703939 4 -rw-r--r-- 1 liang liang 124 5月 11 07:21 /home/liang/.bashrc 1703940 4 drwxr-xr-x 2 liang liang 4096 11月 12 2010 /home/liang/.gnome2 1703995 4 -rw------- 1 liang liang 297 8月 3 05:29 /home/liang/.bash_history 1703941 4 -rw-r--r-- 1 liang liang 176 5月 11 07:21 /home/liang/.bash_profile 1703942 4 -rw-r--r-- 1 liang liang 18 5月 11 07:21 /home/liang/.bash_logout 1704026 4 drwx------ 3 liang ggg 4096 8月 17 00:50 /home/ggg 1704027 4 -rw-r--r-- 1 liang ggg 124 5月 11 07:21 /home/ggg/.bashrc 1704028 4 drwxr-xr-x 2 liang ggg 4096 11月 12 2010 /home/ggg/.gnome2 1704029 4 -rw-r--r-- 1 liang ggg 176 5月 11 07:21 /home/ggg/.bash_profile 1704030 4 -rw-r--r-- 1 liang ggg 18 5月 11 07:21 /home/ggg/.bash_logout #根据用户组名查找 [root@liang testdir]# find /home -group feng -ls 1703943 4 drwx------ 3 feng feng 4096 8月 3 02:16 /home/feng 1703944 4 -rw-r--r-- 1 feng feng 124 5月 11 07:21 /home/feng/.bashrc 1703945 4 drwxr-xr-x 2 feng feng 4096 11月 12 2010 /home/feng/.gnome2 1703946 4 -rw-r--r-- 1 feng feng 176 5月 11 07:21 /home/feng/.bash_profile 1703947 4 -rw-r--r-- 1 feng feng 18 5月 11 07:21 /home/feng/.bash_logout #根据用户组的GID查找 [root@liang testdir]# find /home -gid 501 -ls 1703943 4 drwx------ 3 feng feng 4096 8月 3 02:16 /home/feng 1703944 4 -rw-r--r-- 1 feng feng 124 5月 11 07:21 /home/feng/.bashrc 1703945 4 drwxr-xr-x 2 feng feng 4096 11月 12 2010 /home/feng/.gnome2 1703946 4 -rw-r--r-- 1 feng feng 176 5月 11 07:21 /home/feng/.bash_profile 1703947 4 -rw-r--r-- 1 feng feng 18 5月 11 07:21 /home/feng/.bash_logout
-nouser:查找没有属主的文件
-nogroup:查找没有属组的文件
#查找/home/目录下没有属组的所有文件 [root@liang liang]# find /home -nogroup -ls 1704026 4 drwx------ 3 ggg 4334 4096 8月 17 00:50 /home/ggg 1704027 4 -rw-r--r-- 1 ggg 4334 124 5月 11 07:21 /home/ggg/.bashrc 1704028 4 drwxr-xr-x 2 ggg 4334 4096 11月 12 2010 /home/ggg/.gnome2 1704029 4 -rw-r--r-- 1 ggg 4334 176 5月 11 07:21 /home/ggg/.bash_profile 1704030 4 -rw-r--r-- 1 ggg 4334 18 5月 11 07:21 /home/ggg/.bash_logout #查找/home/目录下没有属主的所有文件 [root@liang liang]# find /home -nouser -ls 2097156 4 drwx------ 3 4321 root 4096 8月 3 04:10 /home/test 2097157 4 -rw-r--r-- 1 4321 root 124 5月 11 07:21 /home/test/.bashrc 2097158 4 drwxr-xr-x 2 4321 root 4096 11月 12 2010 /home/test/.gnome2 2097159 4 -rw-r--r-- 1 4321 root 176 5月 11 07:21 /home/test/.bash_profile 2097160 4 -rw-r--r-- 1 4321 root 18 5月 11 07:21 /home/test/.bash_logout
-type TYPE:根据文件类型进行查找,文件类型包括以下几种:
f:普通文件
d:目录文件
l:符号链接文件
s:套接字文件
b:块设备文件
c:字符设备文件
p:管道文件
#查找/home目录下的所有普通文件 [root@liang liang]# find /home -type f #查找/home目录下的所有目录文件 [root@liang liang]# find /home -type d
-size [+|-]#UNIT:“#”代表数字,按照文件大小来查找,UNIT代表单位,常用单位有k、M、G
#UNIT表示的范围是:(#-1,#]
-#UNIT表示的范围是:[0,#-1]
+#UNIT表示的范围是:(#,∞)
#查找/usr目录下大小为10M的文件,其实查到的是9-10M之间的文件 [root@liang liang]# find /usr -size 10M #查找/usr目录下大于10M的文件 [root@liang liang]# find /usr -size +10M #查找/usr目录下小于等于10M的文件 [root@liang liang]# find /usr -size -11M
以下“#”表示数字
-atime [+|-]#:根据访问时间戳查找,以“天”为单位
-amin [+|-]#:根据访问时间戳查找,以“分钟”为单位
-mtime [+|-]#:根据修改时间戳查找,以“天”为单位
-mmin [+|-]#:根据修改时间戳查找,以“分钟”为单位
-ctime [+|-]#:根据状态变更时间戳查找,以“天”为单位
-cmin [+|-]#:根据状态变更时间戳查找,以“分钟”为单位
#表示的范围是:[#,#-1)
-#表示的范围是:[0,#)
+#表示的范围是:[#+1,∞]
#查找/home目录下前3分钟时访问的文件,实际查找的是前2-3分钟之间访问的文件 [root@liang liang]# find /home -amin 3 #查找/home目录下3分钟内访问的文件 [root@liang liang]# find /home -amin -3 #查找/home目录下3分钟前访问的文件 [root@liang liang]# find /home -amin +2
-perm MODE:根据权限进行文件查找,精确匹配权限
-perm -MODE:根据权限进行文件查找,每一类(u,g,o)对象都必须同时拥有指定的权限,“与”关系。如-222表示对应的u、g、o三者都有写权限的文件。0表示不关注,如-220表示对应的u、g两者都有写权限的文件。
-perm /MODE:centos7之前的版本还可以用-perm +MODE表示,也是根据权限进行文件查找,任何一类(u,g,o)对象中只要有一位匹配即可,或关系。如/222表示对应的u,g,o三者中任何一个有写权限的文件。
#查找/etc/目录下权限为644的所有文件 [root@liang liang]# find /etc/ -perm 644 #查找/etc/目录下任何一类用户有执行权限的所有文件 [root@liang liang]# find /etc/ -perm /111 #查找/etc/目录下所有用户都有执行权限的所有文件 [root@liang liang]# find /etc/ -perm -111 #查找/etc/目录下其他用户有执行权限的所有文件 [root@liang liang]# find /etc/ -perm -001
处理动作
-print:find命令默认的处理动作,将查找到的文件显示至屏幕上
-ls:类似与对查找到的文件执行“ls -l”命令
#查找当前目录下名为network的文件,使用默认动作处理查找到的文件 [root@liang7 etc]# find -name network ./sysconfig/network ./rc.d/init.d/network ./vmware-tools/scripts/vmware/network #查找当前目录下名为network的文件,使用-print选项处理查找到的问及那 [root@liang7 etc]# find -name network -print ./sysconfig/network ./rc.d/init.d/network ./vmware-tools/scripts/vmware/network #查找当前目录下名为network的文件,使用-ls选项处理查找到的文件 [root@liang7 etc]# find -name network -ls 137432923 4 -rw-r--r-- 1 root root 22 Jul 21 02:52 ./sysconfig/network 939715 8 -rwxr-xr-x 1 root root 6630 Sep 16 2015 ./rc.d/init.d/network 269689071 16 -rwxr-xr-x 1 root root 14638 Nov 21 2015 ./vmware-tools/scripts/vmware/network
-delete:删除查找到的文件全部删除(此选项不做演示)
-fls file:将查找到的所有文件的长格式信息保存至指定文件中
#查找当前目录下名为network的文件,使用-fls选项将查找到的文件的长格式结果保存在find.log文件中 [root@liang7 etc]# find -name network -fls find.log #查看保存到find.log文件中的结果 [root@liang7 etc]# cat find.log 137432923 4 -rw-r--r-- 1 root root 22 Jul 21 02:52 ./sysconfig/network 939715 8 -rwxr-xr-x 1 root root 6630 Sep 16 2015 ./rc.d/init.d/network 269689071 16 -rwxr-xr-x 1 root root 14638 Nov 21 2015 ./vmware-tools/scripts/vmware/network
-ok CMMAND {} \;:对查找到的每个文件执行由COMMAND指定的命令,并且对于每个文件执行命令前都会交互式的要求用户确认
-exec CMMAND {} \;:对查找到的每个文件执行由COMMAND指定的命令,与-ok不同的是没有交互式提醒,直接进行CMMAND的操作,不需要用户确认
#使用-exec选项进行备份,要求以“.orig”作为扩展名备份当前目录下以“.conf”结尾的配置文件 [root@liang7 testdir]# find -name "*\.conf" -exec cp {} {}.orig \; #查看备份后的文件 [root@liang7 testdir]# find -name "*.orig" ./fonts/conf.d/66-sil-abyssinica.conf.orig ./fonts/conf.d/59-liberation-mono.conf.orig ./fonts/conf.d/65-0-lohit-tamil.conf.orig ... #提示修改当前目录下其他用户具有写权限的普通文件 [root@liang7 testdir]# find -type f -perm -002 -ok chmod o-w {} \; < chmod ... ./yum.conf > ? y #查看修改权限后的文件 [root@liang7 testdir]# find -name yum.conf -ls 774 4 -rw-rw-r-- 1 root root 970 Aug 16 22:18 ./yum.conf
以上命令中用到的“{}”的作用是引用find查找到的文件名称自身,但是有时候查找到的文件有很多,将会超出后面命令的参数范围,这时后面的命令执行时将会提示错误,这种情况下可以使用xargs命令规避此问题。
find | xargs CMMAND
#查找当前目录下所有以“.orig”结尾的文件并删除 [root@liang7 testdir]# find -name "*.orig" | xargs rm #查看删除结果 [root@liang7 testdir]# find -name "*.orig" | wc -l 0
查找条件之间的逻辑关系
find命令可以同时跟多个查找条件,默认情况下多个查找条件之间的关系是“与”关系。多个查找条件之间的关系有如下几种:
-a:“与”关系,比如查找/etc目录下属主为test用户并且具有执行权限的文件,这时两多个查找条件之间需要使用-a选项,默认情况下就是-a;
#默认情况下的写法 [root@liang7 testdir]# find /etc -user test -perm /100 #使用-a选项的写法 [root@liang7 testdir]# find /etc -user test -a -perm /100
-o:“或”关系,比如查找当前目录下以 “.sh”结尾的文件或查找以“.conf”f结尾的文件,这时两个查找条件之间需要使用-o选项;
#使用-o选项的写法 [root@liang7 testdir]# find -name "*.sh" -o -name "*.conf"
-not或 !:“非”选项,比如查找当前目录下除了test用户外的所有文件,这时指定用户的条件参数前需要使用-not选项;
#使用-not选项的写法 [root@liang7 testdir]# find -not -user test #使用!的写法 [root@liang7 testdir]# find ! -user test
-a,-o,-not三个选项同时使用时,也是有优先级之分的。
-a的优先级要高于-o的优先级,如果查找条件中同时出现-a和-o选项,则先执行-a后执行-o,如:A -o B C,其执行的结果是满足条件A或满足条件BC,如果想实现满足条件A或B,且满足条件C,需要使用小括号将A或B括起来,如(A -o B) C 。
#查找当前系统上没有属主或属组,且最近一周没有被访问过的文件 [root@liang7 testdir]# find / \( -nouser -o -nogroup \) -atime -7
当使用-not选项且将多个查找条件用小括号括起来是需要注意德·摩根定律,该定律的表示方法如下:
(非P)或(非Q)=非(P 且 Q)即(! P)-o (! Q)=! (P -a Q)
(非P)且(非Q)=非(P 或 Q)即(! P)-a (! Q)=! (P -o Q)
#查找/var目录下不属于root、lp、gdm的所有文件(带有小括号的写法) [root@liang7 testdir]# find /var -not \( -user root -o -user lp -o -user gdm \) #查找/var目录下不属于root、lp、gdm的所有文件(不使用小括号的写法) [root@liang7 testdir]# find /var -not -user root -not -user lp -not -user gdm #查找/var目录下最近一周内其内容修改过,同时属主不为root,也不是postfix的文件(带有小括号的写法) [root@liang7 testdir]# find /var -mtime -7 -not \( -user root -o -user postfix \) #查找/var目录下最近一周内其内容修改过,同时属主不为root,也不是postfix的文件(不使用小括号的写法) [root@liang7 testdir]# find /var -mtime -7 -not -user root -not -user postfix
转载于:https://blog.51cto.com/fengliang/1839397