Linux相识相知文件查找(locate/find)

Posted follow your heart.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux相识相知文件查找(locate/find)相关的知识,希望对你有一定的参考价值。

在用linux操作系统的时候,当我们忘记之前某个文件存储的位置,但是知道其文件名或者模糊的知道其文件名,我们都可以通过文件查找工具来查找,linux提供两种常用的查找工具,locate和find,在日常使用中后者比前者较前者功能更强大更具有实时性,下面我们就这两种工具来谈一谈她们的使用方法。

 

Locate

locate是基于实现构建好的索引库(索引库可以理解成文件路径的集合),索引库的位置放在/var/lib/mlocate/mlocate.db文件里面,系统一般一天会自动更新一次,也可以使用updatedb手动更新,要注意的是,索引库的构建过程需要遍历整个文件系统,非常消耗系统资源。

locate的特点是查找的速度快,比find快很多,因为它只在查找索引库,而find会遍历整个文件系统的路径。快的好处自然也给locate带来的缺点,就是它并非是实时查找,意思就是你如果刚刚创建了一个文件,但是你忘记了其路径,只记得其名称,那么这个时候就不建议使用locate,因为索引数据库没有更新,你使用locate查不到,除非你走运,定期更新的时间刚好在创建文件完文件之后,locate在匹配文件名的时候是模糊匹配。

下面我们就来介绍一下locate的用法:

locate

NAME:通过文件名查找文件
SYNOPSIS:locate [OPTION]... PATTERN...
-b:只匹配路径中的基名;
-c:输出符合条件文件的数目
-r:使用基本正则表达式
--regex:使用扩展正则表达式
-i:忽略大小写
-q:安静模式,不会有任何输出

举例1:查找含有"passwd"的文件名

[root@localhost ~]# locate  passwd
/etc/passwd
/etc/passwd-
/etc/pam.d/passwd
/etc/security/opasswd
/usr/bin/gpasswd
/usr/bin/grub2-mkpasswd-pbkdf2
......(省略)
/usr/share/doc/passwd-0.79/AUTHORS
/usr/share/doc/passwd-0.79/COPYING
/usr/share/doc/passwd-0.79/ChangeLog
/usr/share/doc/passwd-0.79/NEWS
/usr/share/vim/vim74/ftplugin/passwd.vim
/usr/share/vim/vim74/syntax/passwd.vim

我们会发现,非基名中存在passwd也会被匹配出来,我们可以使用"-b"选项来匹配:

[root@localhost ~]# locate -b  passwd
/etc/passwd
/etc/passwd-
/etc/pam.d/passwd
/etc/security/opasswd
/usr/bin/gpasswd
/usr/bin/grub2-mkpasswd-pbkdf2
/usr/bin/kdepasswd
/usr/bin/kpasswd
/usr/bin/lppasswd
/usr/bin/passwd
/usr/bin/vncpasswd
......
/usr/share/man/zh_CN/man8/chpasswd.8.gz
/usr/share/man/zh_CN/man8/smbpasswd.8.gz
/usr/share/man/zh_TW/man8/chpasswd.8.gz
/usr/share/ruby/webrick/httpauth/htpasswd.rb
/usr/share/vim/vim74/ftplugin/passwd.vim
/usr/share/vim/vim74/syntax/passwd.vim
看输出的显示结果,只有基名中含有"passwd"的才会被匹配
举例2:查找只有基名中含有"passwd"的文件名的数目
[root@localhost ~]# locate -bc  passwd
155

 举例3:查找基名中只有"passwd"文件的文件

[root@localhost ~]# locate -br "\\<passwd$"
/etc/passwd
/etc/pam.d/passwd
/usr/bin/passwd
/usr/share/bash-completion/completions/passwd

updatedb的配置文件在/etc/updatedb.conf

PRUNE_BIND_MOUNTS = "yes"
PRUNEFS = "9p afs anon_inodefs auto autofs bdev binfmt_misc cgroup cifs coda configfs cpuset debugfs devpts ecryptfs exofs fuse fuse.sshfs fusectl gfs gfs2 gpfs hugetlbfs inotifyfs iso9660 jffs2 lustre mqueue ncpfs nfs nfs4 nfsd pipefs proc ramfs rootfs rpc_pipefs securityfs selinuxfs sfs sockfs sysfs tmpfs ubifs udf usbfs"
PRUNENAMES = ".git .hg .svn"
PRUNEPATHS = "/afs /media /mnt /net /sfs /tmp /udev /var/cache/ccache /var/lib/yum/yumdb /var/spool/cups /var/spool/squid /var/tmp"

PRUNE_BIND_MOUNTS:表示是否限制搜索

PRUNEFS:所列的文件系统,查找的时候不进行查找

PRUNENAMES:所列的后缀名不进行查找

PRUNEPATHS:所列的文件路径下的文件不进行查找

实时性检测

[root@localhost etc]# touch mypasswd
[root@localhost etc]# 
[root@localhost etc]# locate mypasswd
[root@localhost etc]# 
[root@localhost etc]# updatedb
[root@localhost etc]# 
[root@localhost etc]# locate mypasswd
/etc/mypasswd

在etc下我们创建mypasswd,立马使用locate命令查找并不能查找,使用updatedb之后更新之后索引数据库之后就可以查找到了。

 

find

通过直面意思我们就知道find就是“查找”的意思,find的是一个实时查找命令,它会在查找的时候会遍历指定起始路径下文件系统层级结构完成文件查找,所以其缺点就是查找的速度要比locate慢。

下面我们就要介绍一下find的使用方法:

NAME:递归地在层次目录中处理文件
SYNOPSIS:find  [OPTIONS]  [查找起始路径]  [查找条件]  [处理动作]
查找路径:可以指定搜索目标的其实路径,默认为当前目录
查找条件:可以指定查找标准,可以根据文件名、大小、类型、从属关系、权限等匹配
处理动作:对符合查找条件的文件做出操作,比如删除等,默认行为为至标准输出

find的选项不常用,了解可使用man find来查看,下面主要来说明一下查找条件和处理动作,find的状态返回值为布尔值,查找的到则返回"0",查找不到则返回大于"0"的数字。

查找条件:

1.根据文件名查找

-name  "pattern"
-iname "pattern"   #支持的通配符的模式,i为不区分大小写
-regex "pattern"   #基于正则表达式模式查找文件,注意这里匹配的不是文件本身,而是包含这个文件路径

举例:

[root@localhost etc]# find /etc/ -name "passwd"    #搜索/etc目录下含有passwd的文件
/etc/pam.d/passwd
/etc/passwd
[root@localhost etc]# find /etc/ -iname "passwd"   #搜索/etc目录下含有passwd的文件,忽略字符大小写
/etc/pam.d/passwd
/etc/passwd
/etc/Passwd
[root@localhost etc]# find /etc/ -iname "passwd[0-9]"  #搜索/etc目录下含有passwd且后面还有0-9任意一个数字的文件
/etc/passwd1
[root@localhost etc]# find /etc/ -regex \'/etc/passwd.?\'  #搜索/etc目录下含基名以passwd开头且后面可以有任意字符也可以没有的文件
/etc/passwd
/etc/passwd-
/etc/passwd1

 

2.根据文件从属关系查找

-user USERNAME:查找属主为指定用户的文件
-group GROUPNAME:查找属组为指定组的文件
-uid UID:查找属主为指定UID的文件
-gid GID:查找属组为指定的GID的文件
-nouser:查找没有属主的文件
-nogroup:查找没有属组的文件

举例:

[root@localhost ~]# find /tmp/ -user frank -ls   #输出tmp下属主是frank的文件,-ls后面再讲
9336543    0 drwx------   2 frank    frank          27 7月 16 04:46 /tmp/kde-frank
9357728    4 -rw-rw-r--   1 frank    frank         132 7月 16 04:46 /tmp/kde-frank/xauth-1000-_0
9357736    0 drwx------   2 frank    frank          34 7月 16 04:47 /tmp/akonadi-frank.yFqCJF
9357758    0 srwxrwxr-x   1 frank    frank           0 7月 16 04:46 /tmp/akonadi-frank.yFqCJF/akonadiserver.socket
27750615    0 drwx------   2 frank    frank           6 7月 16 04:47 /tmp/.esd-1000
[root@localhost ~]# find /tmp/ -group frank -ls  #输出/tmp目录下属组是frank的文件
9336543    0 drwx------   2 frank    frank          27 7月 16 04:46 /tmp/kde-frank
9357728    4 -rw-rw-r--   1 frank    frank         132 7月 16 04:46 /tmp/kde-frank/xauth-1000-_0
9357736    0 drwx------   2 frank    frank          34 7月 16 04:47 /tmp/akonadi-frank.yFqCJF
9357758    0 srwxrwxr-x   1 frank    frank           0 7月 16 04:46 /tmp/akonadi-frank.yFqCJF/akonadiserver.socket
27750615    0 drwx------   2 frank    frank           6 7月 16 04:47 /tmp/.esd-1000
[root@localhost ~]# find /tmp/ -uid 1000 #显示/tmp下uid为1000的文件
/tmp/kde-frank
/tmp/kde-frank/xauth-1000-_0
/tmp/akonadi-frank.yFqCJF
/tmp/akonadi-frank.yFqCJF/akonadiserver.socket
/tmp/.esd-1000
[root@localhost ~]# find /tmp/ -nouser  -ls  #显示/tmp下没有属主的文件,如果一个用户创建一个文件之后,用户被删除,则显示为原来的uid和gid,不会显示属组合属主
375722    0 -rw-rw-r--   1 1003     1003            0 7月 23 00:08 /tmp/mygrp.txt

 

3.根据文件类型查找

-type TYPE
TYPE可以为以下:
f:普通文件
d:目录文件
l:符号链接
b:块设备文件
c:字符设备文件
p:管道文件
s:套接字文件

举例:

[root@localhost ~]# find /dev/ -type b  #查找dev目录下的块设备文件
/dev/dm-2
/dev/dm-1
/dev/dm-0
/dev/sr0
/dev/sda2
/dev/sda1
/dev/sda

 

4.根据文件大小查找

一般格式为   -size  [+|-]#UNIT     UNIT常用单位为:k,M,G

-size  #UNIT:匹配的大小范围是#及大于#-1的文件

举例:匹配3K的大小,大于2K及小于等于3K的都会被匹配

[root@localhost ~]# ll -h
总用量 16K
-rw-------. 1 root root 2.1K 7月  16 04:45 anaconda-ks.cfg
-rw-r--r--. 1 root root 2.1K 7月  16 04:45 initial-setup-ks.cfg
-rw-r--r--. 1 root root  555 7月  19 10:04 TEST
-rw-------. 1 root root 3.0K 7月  23 00:23 test.txt
[root@localhost ~]# find  -size 3k -ls
27734414    4 -rw-------   1 root     root         2094 7月 16 04:45 ./anaconda-ks.cfg
27734452    4 -rw-r--r--   1 root     root         2142 7月 16 04:45 ./initial-setup-ks.cfg
25795843    4 -rw-------   1 root     root         3070 7月 23 00:23 ./test.txt

-size -#UNIT:匹配的范围是文件大小大于0且小于等于#-1的文件

举例:

[root@localhost ~]# find  -size -3k -ls
25165889    0 dr-xr-x---   6 root     root          261 7月 23 00:23 .
27728080    4 -rw-r--r--   1 root     root           18 12月 29  2013 ./.bash_logout
27728081    4 -rw-r--r--   1 root     root          176 12月 29  2013 ./.bash_profile
27728082    4 -rw-r--r--   1 root     root          176 12月 29  2013 ./.bashrc
27728083    4 -rw-r--r--   1 root     root          100 12月 29  2013 ./.cshrc
27728084    4 -rw-r--r--   1 root     root          129 12月 29  2013 ./.tcshrc
1327848    0 drwx------   3 root     root           25 7月 16 04:45 ./.dbus
9336529    0 drwx------   2 root     root           48 7月 16 04:45 ./.dbus/session-bus
9336530    4 -rw-r--r--   1 root     root          462 7月 16 04:45 ./.dbus/session-bus/6155eeadc72c4d45b9ead1cf2a8c65a0-9
....(省略)

-size +#UNIT:匹配的是大于#的文件

[root@localhost ~]# ll -ah    
总用量 52K
dr-xr-x---.  6 root root  261 7月  23 00:23 .
dr-xr-xr-x. 17 root root  233 7月  16 04:44 ..
-rw-------.  1 root root 2.1K 7月  16 04:45 anaconda-ks.cfg
-rw-------.  1 root root 4.8K 7月  19 10:14 .bash_history
-rw-r--r--.  1 root root   18 12月 29 2013 .bash_logout
-rw-r--r--.  1 root root  176 12月 29 2013 .bash_profile
-rw-r--r--.  1 root root  176 12月 29 2013 .bashrc
drwx------.  4 root root   31 7月  16 04:46 .cache
drwxr-xr-x.  3 root root   40 7月  16 04:46 .config
-rw-r--r--.  1 root root  100 12月 29 2013 .cshrc
drwx------.  3 root root   25 7月  16 04:45 .dbus
-rw-r--r--.  1 root root 2.1K 7月  16 04:45 initial-setup-ks.cfg
drwxr-xr-x.  3 root root  123 7月  16 04:45 .kde
-rw-r--r--.  1 root root  129 12月 29 2013 .tcshrc
-rw-r--r--.  1 root root  555 7月  19 10:04 TEST
-rw-------.  1 root root 3.0K 7月  23 00:23 test.txt
-rw-------.  1 root root 6.4K 7月  23 00:23 .viminfo
[root@localhost ~]# find -size +3k      #匹配大于3k的文件
./.config/Trolltech.conf
./.bash_history
./.viminfo

 

5.根据时间戳查找

可根据天或者分钟查找

根据天:
-atime n:对文件的最近一次访问是在 n*24 小时之前
-mtime n:对文件数据的最近一次修改是在 n*24 小时之前
-ctime n:对文件状态的最近一次修改是在 n*24 小时之前,当元数据修改时
根据分钟:
-amin n:对文件的最近一次访问是在n分钟之前
-mmin n:对文件数据的最近一次修改是在n分钟之前
-cmin n:对文件状态的最近一次修改是在n分钟之前,当元数据修改时

同时也支持 "-atime  [+|-]#"

情景1:find -atime 1 :如下图,如果现在时间是0:56分,那么查找1天前访问过的文件为哪些,查找的就是2017-7-21-0:56(不包含)到2017-7-21-00:56(包含)分访问的文件,

情景2:find  -atime -1:使用"-",查找的是1天之内,如下图,如果现在是0:56,则不包括2017-7-22-0:56

 

情景3:find -atime +1:使用符号"+",表示的是查找1+1之前访问过的文件,如果现在0:56,则2017-7-21-00:56(包括00:56)之前访问过的文件才会被匹配

 

其他的ctime、mtime和分钟的查找类似,这里就不再敖述了。测试可以使用touch命令修改时间戳的方式来尝试

touch -t 201707210130  mytime.txt 

 

 6.根据权限查找

格式:-perm [/|-]mode
mode:精确匹配权限
/mode:任何一类用户(u,g,o)的权限中的任何一位(r,w,x)符合条件即满足,9位权限之间存在“或”关系
-mode:每一类用户(u,g,o)的权限每一位同时符合条件即满足;9位权限之间存在“与”关系

 举例1:精确匹配/tmp/myper目录下权限是411的文件

[root@localhost ~]# find /tmp/myper/ -perm 422 -ls
654578    0 -r---w--w-   1 root     root            0 7月 23 07:32 /tmp/myper/myper2

 举例2:匹配/tmp/myper其他用户有执行权限的文件

[root@localhost ~]# find /tmp/myper/ -perm /001 -ls
18772160    0 drwxr-xr-x   2 root     root           62 7月 23 07:38 /tmp/myper/
654577    0 -rw---x--x   1 root     root            0 7月 23 07:32 /tmp/myper/myper1
654579    0 ---xr-xr-x   1 root     root            0 7月 23 07:32 /tmp/myper/myper3
654580    0 -rwxr-xr-x   1 root     root            0 7月 23 07:32 /tmp/myper/myper4

 举例3:匹配/tmp/myper下user权限至少可读,group和others权限至少可以执行的文件

[root@localhost ~]# find /tmp/myper/ -perm -411 -ls
18772160    0 drwxr-xr-x   2 root     root           62 7月 23 07:38 /tmp/myper/
654577    0 -rw---x--x   1 root     root            0 7月 23 07:32 /tmp/myper/myper1
654580    0 -rwxr-xr-x   1 root     root            0 7月 23 07:32 /tmp/myper/myper4

 

 处理动作:

-print:输出至标准输出,默认选项
-ls:类似对查到的文件执行"ls -l"命令
-delete:删除查到的文件
-fls /PATE/TO/SOMEFILE:把查到的所有文件的长格式信息保存至指定的文件
-ok COMMAND {} \\; :对查到的每个文件执行由COMMAND表示的命令,每次操作都由用户确认
-exec COMMAND {} \\; :对查到的每个文件执行由COMMAND表示的命令,无需用户确认

find传递查到的文件路径至后面的命令时,是先查找所有符合条件的路径,并一次性传递给后面的命令的,但是有些命令不能接受过长的参数,此时命令会执行失败,可以使用以下方法:

find  | xargs COMMAND

xargs可以读取标准输出的内容,并以空白字元或者断行字元作为分隔符,分隔为arguments,然后一一传递给COMMAND执行

举例:查看符合条件文件的文件元数据

[root@localhost ~]# find /tmp/myper/ -perm -411  |    stat
stat: 缺少操作数
Try \'stat --help\' for more information.
[root@localhost ~]# find /tmp/myper/ -perm -411  |  xargs  stat
  文件:"/tmp/myper/"
  大小:62            块:0          IO 块:4096   目录
设备:fd00h/64768d    Inode:18772160    硬链接:2
权限:(0755/drwxr-xr-x)  Uid:(    0/    root)   Gid:(    0/    root)
环境:unconfined_u:object_r:user_tmp_t:s0
最近访问:2017-07-23 07:38:40.570675351 +0800
最近更改:2017-07-23 07:38:33.192894947 +0800
最近改动:2017-07-23 07:38:33.192894947 +0800
创建时间:-
  文件:"/tmp/myper/myper1"
  大小:7             块:8          IO 块:4096   普通文件
设备:fd00h/64768d    Inode:654577      硬链接:1
权限:(0611/-rw---x--x)  Uid:(    0/    root)   Gid:(    0/    root)
环境:unconfined_u:object_r:user_tmp_t:s0
最近访问:2017-07-23 07:58:31.699745976 +0800
最近更改:2017-07-23 07:57:38.304747287 +0800
最近改动:2017-07-23 07:57:38.304747287 +0800
创建时间:-
  文件:"/tmp/myper/myper4"
  大小:7             块:8          IO 块:4096   普通文件
设备:fd00h/64768d    Inode:654580      硬链接:1
权限:(0755/-rwxr-xr-x)  Uid:(    0/    root)   Gid:(    0/    root)
环境:unconfined_u:object_r:user_tmp_t:s0
最近访问:2017-07-23 07:58:31.699745976 +0800
最近更改:2017-07-23 07:57:53.229457221 +0800
最近改动:2017-07-23 07:57:53.229457221 +0800
创建时间:-

 

 扩展小特性:

在查找的时候多个条件之间的关系:
与:-a  ,默认的关系
或:-o   ,满足一个条件即可
非:-not或者!  ,条件取反
有以下表达式:
!A -a !B = !(A -o B)
!A -o !B = !(A -a B)

 

小练习:
练习1:找出/tmp目录下属主为非root的所有文件
find /tmp/  -not -user root  -ls
View Code

 练习2:找出/tmp目录下文件名中不包含fstab字符串的文件

find /tmp/ -not -name fstab
View Code

 练习3:找出/tmp目录下属主为非root,而且文件名不包含fstab字符串的文件

find /tmp/ ! \\( -user root -o -name fstab \\)
View Code

 练习4:查找/var目录下属主为root,且属组为mail的所有文件或目录

find  /var/ -user root -a -group mail -ls
View Code

 练习5:查找/usr目录下不属于用户root, bin或hadoop的所有文件或目录;用两种方法

find /usr/ -not -user root -a -not -user bin -a -not -user hadoop
find /usr/ -not \\( -user root -o -user bin -o -user hadoop \\) 
View Code

 练习6:查找/etc目录下最近一周内其内容修改过,且属主不是root用户也不是hadoop用户的文件或目录

find /etc/ -mtime 7  -a  -not -user root -a -not -user hadoop 
View Code

 练习7:查找当前系统上没有属或属组,且最近一周内曾被访问过的文件或目录

find  /  \\( -nouser -o -nogroup \\)  -atime  -7 
View Code

 练习8:查找/etc目录下大于1M且类型为普通文件的所有文件

find /etc/ -size +1M  -type f  -exec ls -lh {} \\;
View Code

 练习9:查找/etc目录下所有用户都没有写权限的文件

find /etc/  -not  -perm  /222
View Code

 练习10:查找/etc目录至少有一类用户没有执行权限的文件

find /etc/ -not  -perm  -111
View Code

 练习11:查找/etc/init.d/目录下,所有用户都有执行权限,且其它用户有写权限的所有文件

find /etc/init.d/  -perm  -113 
View Code

 

以上是关于Linux相识相知文件查找(locate/find)的主要内容,如果未能解决你的问题,请参考以下文章

Linux查找文件(locate | find)

linux相识相知sed命令

Linux相识相知rpm包管理

linux 文件查找 (locate 与 find)

linux命令: 两个查找工具 locate,find

Linux之find文件(目录)查找