linux文件查找-find命令详解


我们在前面几篇文章中已经接触到了大量和文件与目录操作相关的命令,比如ls、cd、touch、mkdir、cp、mv等。本章就来详细介绍这些命令的用法。 文件的查找是我们在linux下经常遇到的问题。 我们之前在讲解linux命令的时候已经接触过一些和查找有关的命令了,那就是which和whereis, 不过这两个命令查找的都是和命令相关的文件。关于which和whereis命令的详细信息参考: 什么是linux命令 还有两个更强大的和文件搜索相关的命令,一个是locate,另一个是find。 locate利用数据库来搜索文件,速度要比find命令快,而find命令直接搜索磁盘的文件系统,如果磁盘性能比较差的话,那么find可能会花费更多的时间

find命令

回到顶部
find命令会真正的遍历磁盘目录,所以在搜索能力上比locate命令更全面更加强大,但是相应的效率可能会比locate低。 find属于重度搜索,locate不一定能搜索出来的东西,可能用find就可以搜素出来。 find命令常用格式如下:
              [root@initroot ~]# find [PATH] [option] [action]
            
find命令的选项参数非常的多,这也正是find命令的强大之处。

1.与时间有关的选项与参数

选项与参数:
有三种文件时间,分别是-atime, -ctime和-mtime, 这里以-mtime说明:
-mtime n :n为数字,表示在n天之前的一天之内被修改过文件内容的文件名;
-mtime +n :列出在 n 天之前(不含 n 天本身)被修改过文件内容的文件名;
-mtime -n :列出在n天之内(含n天本身)被修改过文件内容的文件名。
-newer file :file为一个存在的文件,列出比file还要新的文件名
将过去24小时内系统中有更动过内容(mtime)的文件列出,也就是一天内被改动过内容的文件:
              [root@initroot ~]# find / -mtime 0
            
0表示目前的时间,从现在开始到24小时前,有变动过内容的文件都会被列出来! 将三天前的24小时内系统中被变动过内容的文件列出:
              [root@initroot ~]# find / -mtime 3
            
寻找/etc目录下文件日期比/etc/passwd新的文件:
              [root@initroot ~]# find /etc -newer /etc/passwd
            
如果想要找出/var目录下4天内被更动过的文件名,可以用find /var -mtime -4,如果是4天前的那一天就用find /var -mtime 4。 有没有加上+,-差别很大!我们可以用简单的图示来说明一下:
find命令时间参数意义 图.find命令时间参数意义
最右边为目前的时间,越往左代表越早之前的时间。
+4代表大于等于5天前的文件名:find /var -mtime +4
-4代表小于等于4天内的文件名:find /var -mtime -4
4则是代表4-5那一天的文件名:find /var -mtime 4

2.与使用者或组名有关的选项与参数

选项与参数:
-uid n :n为用户的账号ID,即UID;UID必须是记录在/etc/passwd文件中用户帐号ID;
-gid n :n为用户组的ID,即GID;GID必须是记录在/etc/group文件中用户组ID;
-user name :name为用户账号名称,例如当前登录帐号为peter;
-group name :name为用户组名,例如initroot;
-nouser :寻找文件的拥有者没有记录在/etc/passwd中的文件!
-nogroup :寻找文件的拥有群组没有记录在/etc/group中的文件!
当你自行安装软件时,很可能该软件的属性当中并没有文件拥有者,这是可能的!在这个时候,就可以使用-nouser与-nogroup选项搜寻。
搜寻/home目录下属于peter的文件:
              [root@initroot ~]# find /home -user peter
            
-user选项非常有用,当我们要找出某个用户的所有文件时,就可以利用-user选项将属于某个用户的所有文件都找出来!
搜寻系统中不属于任何人的文件:
              [root@initroot ~]# find / -nouser
            
系统中可能会存在不属于任何人的文件,比如从网络上下载的文件有可能不属于系统中的已经注册登记的用户,或者你将系统中的某个帐号删除了, 而这个帐号之前已经在系统中建立了很多文件。一旦帐号被删除,这些文件的所有者就不会记录在/etc/passwd文件中了,也就成了不属于任何人的文件了。 要想寻找这样的文件那就用-nouser选项,同样的道理,寻找不属于任何用户组的文件,那就加上-nogroup选项。

3.与文件权限及名称有关的选项与参数

选项与参数:
-name filename: 搜寻文件名为filename的文件;
-size [+-]SIZE:搜寻比SIZE大(+)或小(-)的文件。SIZE的单位有:c:代表byte, k:代表1024bytes。例如要找比50KB还要大的文件,就是-size +50k;
-type TYPE : 搜寻文件的类型为TYPE,TYPE可以是以下几种类型:一般普通文件f, 块设备文件b, 字符设备文件c,目录d, 链接文件l, socket文件s,FIFO文件p等。
-perm mode :搜寻文件权限等于mode的文件,这个mode为类似chmod的属性值,举例来说, -rwsr-xr-x的数值为 4755 !
-perm -mode :搜寻文件权限必须要全部囊括mode的权限的文件,举例来说,我们要搜寻 -rwxr--r-- ,亦即 0744 的文件,使用 -perm -0744, 当一个文件的权限为 -rwsr-xr-x ,亦即 4755 时,也会被列出来,因为 -rwsr-xr-x 的属性已经囊括了 -rwxr--r-- 的属性了。
-perm /mode :搜寻文件权限包含任一mode的权限的文件,举例来说,我们搜寻-rwxr-xr-x ,亦即 -perm /755 时, 但一个文件属性为-rw-------也会被列出来,因为他有-rw.... 的属性存在!
从根目录下查找文件名为passwd的文件:
              [root@initroot ~]# find / -name passwd
            
find会从指定的目录一层一层往下搜索。
从根目录下查找文件名中包含passwd的文件
              [root@initroot ~]# find / -name "*passwd*"
            
-name寻找的文件名是必须完全匹配filename的,如果想要找关键词,可以使用类似*的任意字符来处理
找出/run目录下,文件类型为Socket的文件:
              [root@initroot ~]# find /run -type s
            
从根目录下搜寻含有SGID或SUID或SBIT属性的文件
              [root@initroot ~]# find / -perm /7000
            
7000就是---s--s--t ,那么只要含有s或t的就列出,所以当然要使用/7000, 使用 -7000 表示要同时含有---s--s--t的所有三个权限。而只需要任意一个,就是/7000了
-perm选项的重点在找出特殊权限的文件。 SUID 与 SGID 都可以设置在二进制程序文件上,找出/usr/bin, /usr/sbin这两个目录下, 只要具有SUID 或 SGID就列出来该文件:
              [root@initroot ~]# find /usr/bin /usr/sbin -perm /6000
            
因为 SUID 是 4 分,SGID 2 分,总共为 6 分,因此可用 /6000 来处理这个权限! find后可接多个目录来进行搜寻!

4. 和动作相关的选项与参数:

选项与参数: -exec command :command为其他指令,-exec后面可再接额外的指令来处理搜寻到的结果。 -print :将结果打印到屏幕上,该选项为默认动作选项! 将上例中找到的文件用ls -l列出来:
              [root@initroot ~]# find /usr/bin /usr/sbin -perm /7000 -exec ls -l {} \;
            
-exec选项后面的ls -l就是额外的指令,指令不支持命令别名,所以只能使用ls -l,不可以使用ll!
{}表示由find找到的内容,所以find的结果会被放到{}中
;表示find额外动作的结束,也就是说find的额外动作是由-exec开始到;结束,但是由于;在bash命令上下有特殊的意义,因此用反斜杠\转义。 上述命令的执行可以如下示意图表示: find动作执行示意图 图.find动作执行示意图
找出系统中大于1MB的文件:
              [root@initroot ~]# find / -size +1M
            
通过文件的属性,比如SUID、文件拥有者、文件大小等来搜索文件,利用loacat是无法做到的,此时就显示出find命令的强大了。 find还可以利用通配符来搜索文件名。比如你想要找出/etc目录下文件名中包含httpd的文件:
              [root@initroot ~]# find /etc -name '*httpd*'
            

find命令用于文件的查找。
find命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。 如果使用该命令时,不设置任何参数,则find命令将在当前目录下查找子目录与文件。 并且将查找到的子目录和文件全部进行显示。

列出当前目录及子目录下所有文件和文件夹

find .
在/home目录下查找以.txt结尾的文件名
find /home -name "*.txt"
同上,但忽略大小写
find /home -iname "*.txt"
当前目录及子目录下查找所有以.txt和.pdf结尾的文件
find . \( -name "*.txt" -o -name "*.pdf" \)
find . -name "*.txt" -o -name "*.pdf"
匹配文件路径或者文件
find /usr/ -path "*local*"
基于正则表达式匹配文件路径
find . -regex ".*\(\.txt\|\.pdf\)$"
同上,但忽略大小写
find . -iregex ".*\(\.txt\|\.pdf\)$"
否定参数 找出/home下不是以.txt结尾的文件
find /home ! -name "*.txt"
根据文件类型进行搜索
find . -type 类型参数
类型参数列表:
f 普通文件
l 符号连接
d 目录
c 字符设备
b 块设备
s 套接字
p Fifo
基于目录深度搜索
向下最大深度限制为3
find . -maxdepth 3 -type f
搜索出深度距离当前目录至少2个子目录的所有文件
find . -mindepth 2 -type f
根据文件时间戳进行搜索
find . -type f 时间戳
UNIX/Linux文件系统每个文件都有三种时间戳:
访问时间(-atime/天,-amin/分钟):用户最近一次访问时间。
修改时间(-mtime/天,-mmin/分钟):文件最后一次修改时间。
变化时间(-ctime/天,-cmin/分钟):文件数据元(例如权限等)最后一次修改时间。
搜索最近七天内被访问过的所有文件
find . -type f -atime -7
搜索恰好在七天前被访问过的所有文件
find . -type f -atime 7
搜索超过七天内被访问过的所有文件
find . -type f -atime +7
搜索访问时间超过10分钟的所有文件
find . -type f -amin +10
找出比file.log修改时间更长的所有文件
find . -type f -newer file.log
根据文件大小进行匹配
find . -type f -size 文件大小单元
文件大小单元:
b —— 块(512字节)
c —— 字节
w —— 字(2字节)
k —— 千字节
M —— 兆字节
G —— 吉字节
搜索大于10KB的文件
find . -type f -size +10k
搜索小于10KB的文件
find . -type f -size -10k
搜索等于10KB的文件
find . -type f -size 10k
删除匹配文件
删除当前目录下所有.txt文件
find . -type f -name "*.txt" -delete
根据文件权限/所有权进行匹配
当前目录下搜索出权限为777的文件
find . -type f -perm 777
找出当前目录下权限不是644的php文件
find . -type f -name "*.php" ! -perm 644
找出当前目录用户tom拥有的所有文件
find . -type f -user tom
找出当前目录用户组sunk拥有的所有文件
find . -type f -group sunk
借助-exec选项与其他命令结合使用
找出当前目录下所有root的文件,并把所有权更改为用户tom
find .-type f -user root -exec chown tom {} \;
上例中,{} 用于与-exec选项结合使用来匹配所有文件,然后会被替换为相应的文件名。
找出自己家目录下所有的.txt文件并删除
find $HOME/. -name "*.txt" -ok rm {} \;
上例中,-ok和-exec行为一样,不过它会给出提示,是否执行相应的操作。 查找当前目录下所有.txt文件并把他们拼接起来写入到all.txt文件中
find . -type f -name "*.txt" -exec cat {} \;> all.txt
将30天前的.log文件移动到old目录中
find . -type f -mtime +30 -name "*.log" -exec cp {} old \;
找出当前目录下所有.txt文件并以“File:文件名”的形式打印出来
find . -type f -name "*.txt" -exec printf "File: %s\n" {} \;
因为单行命令中-exec参数中无法使用多个命令,以下方法可以实现在-exec之后接受多条命令
-exec ./text.sh {} \;
搜索但跳出指定的目录
查找当前目录或者子目录下所有.txt文件,但是跳过子目录sk
find . -path "./sk" -prune -o -name "*.txt" -print
find其他技巧收集
要列出所有长度为零的文件
find . -empty

Usage: find [-H] [-L] [-P] [-Olevel] [-D debugopts] [path...] [expression]
default path is the current directory; default expression is -print
expression may consist of: operators, options, tests, and actions:
operators (decreasing precedence; -and is implicit where no others are given):
( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2
EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2
positional options (always true): -daystart -follow -regextype
normal options (always true, specified before other expressions):
-depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
--version -xdev -ignore_readdir_race -noignore_readdir_race
tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N
-cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME
-ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN
-links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE
-nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN
-readable -writable -executable
-wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N
-used N -user NAME -xtype [bcdpfls] -context CONTEXT
actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print
-fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit
-exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;
-execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ;
Valid arguments for -D:
exec, help, opt, rates, search, stat, time, tree
Use '-D help' for a description of the options, or see find(1)
Please see also the documentation at http://www.gnu.org/software/findutils/.
You can report (and track progress on fixing) bugs in the "find"
program via the GNU findutils bug-reporting page at
https://savannah.gnu.org/bugs/?group=findutils or, if
you have no web access, by sending email to bug-findutils@gnu.org.

linux文件总结

6.6 极重要的复习!权限与指令间的关系
我们知道权限对于使用者账号来说是非常重要的,因为他可以限制使用者能不能读取/建立/删除/修改 文件或目录! 在这一章我们介绍了很多文件系统的管理指令,第五章则介绍了很多文件权限的意义。 在这个小节当中, 我们就将这两者结合起来,说明一下什么指令在什么样的权限下才能够运作吧!
^_^ 一、让用户能进入某目录成为『可工作目录』的基本权限为何:
可使用的指令:例如 cd 等变换工作目录的指令;
目录所需权限:用户对这个目录至少需要具有 x 的权限
额外需求:如果用户想要在这个目录内利用 ls 查阅文件名,则用户对此目录还需要 r 的权限。二、用户在某个目录内读取一个文件的基本权限为何?
可使用的指令:例如本章谈到的 cat, more, less 等等
目录所需权限:用户对这个目录至少需要具有 x 权限;
文件所需权限:使用者对文件至少需要具有 r 的权限才行!
三、让使用者可以修改一个文件的基本权限为何?
可使用的指令:例如 nano 或未来要介绍的 vi 编辑器等;
目录所需权限:用户在该文件所在的目录至少要有 x 权限;
文件所需权限:使用者对该文件至少要有 r, w 权限
四、让一个使用者可以建立一个文件的基本权限为何?
目录所需权限:用户在该目录要具有 w,x 的权限,重点在 w 啦!
五、让用户进入某目录并执行该目录下的某个指令之基本权限为何?
目录所需权限:用户在该目录至少要有 x 的权限;
文件所需权限:使用者在该文件至少需要有 x 的权限
例题:
让一个使用者 peter 能够进行『cp /dir1/file1 /dir2』的指令时,请说明 dir1, file1, dir2 的最小所需权限为何?
答:
执行 cp 时, peter 要『能够读取来源文件,并且写入目标文件! 』所以应参考上述第二点与第四点的说明! 因此各 文件/目录的最小权限应该是:
dir1 :至少需要有 x 权限;
file1:至少需要有 r 权限;
dir2 :至少需要有 w, x 权限。
例题:
有一个文件全名为 /home/student/www/index.html ,各相关文件/目录的权限如下:
drwxr-xr-x 23 root
root
4096 Sep 22 12:09 /
drwxr-xr-x 6 root
root
4096 Sep 29 02:21 /home
drwx------ 6 student student 4096 Sep 29 02:23 /home/student
drwxr-xr-x 6 student student 4096 Sep 29 02:24 /home/student/www
-rwxr--r-- 6 student student
369 Sep 29 02:27 /home/student/www/index.html
请问 vbird 这个账号(不属于 student 群组)能否读取 index.html 这个文件呢?
答:
虽然 www 与 index.html 是可以让 vbird 读取的权限,但是因为目录结构是由根目录一层一层读取的, 因此 vbird 可 进入 /home 但是却不可进入 /home/student/ ,既然连进入 /home/student 都不许了, 当然就读不到 index.html 了! 所以答案是『vbird 不会读取到 index.html 的内容』喔!
那要如何修改权限呢?其实只要将 /home/student 的权限修改为最小 711 ,或者直接给予 755 就可以啰! 这可是很 重要的概念喔!

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读