美文网首页Lunix学习
第二十二课 Linux系统中的 find 命令

第二十二课 Linux系统中的 find 命令

作者: Arroganter | 来源:发表于2018-09-05 16:06 被阅读9次

    Linux系统中的 find 命令在查找文件时非常有用而且方便。它可以根据不同的条件来查找文件,例如权限、拥有者、修改日期/时间、文件大小等等。在这篇文章中,我们将学习如何使用 find 命令以及它所提供的选项来查找文件。

    在绝大多数Linux发行版中,你都可以直接使用 find 命令而无需进行任何安装操作。如果你想在linux系统的命令行中变得特别高效,那么 find 是你必须掌握的命令之一。

    find 命令的基本语法如下:

    $ find [path] [option] [expression]
    
    

    一、基本用法

    1.列出当前目录和子目录下的所有文件

    这个命令会列出当前目录以及子目录下的所有文件。

    $ find
    .
    ./abc.txt
    ./subdir
    ./subdir/how.php
    ./cool.php
    
    

    该命令与以下命令效果相同

    $ find .
    $ find . -print
    
    
    2. 查找特殊的目录或路径

    下面的命令会查找当前目录下 test 文件夹中的文件,默认列出所有文件。

    $ find ./test
    ./test
    ./test/abc.txt
    ./test/subdir
    ./test/subdir/how.php
    ./test/cool.php
    
    

    下面的命令用于查找指定名称的文件。

    $ find ./test -name "abc.txt"
    ./test/abc.txt
    
    

    也可以使用通配符

    $ find ./test -name "*.php"
    ./test/subdir/how.php
    ./test/cool.php
    
    

    请注意,所有的文件夹都会被递归地查找。所以,这是用于查找指定扩展名文件的一种非常强大的方式。

    如果我们尝试搜索 / 文件夹,也就是根目录,就会搜索整个文件系统,包括挂载的设备以及网络存储设备。所以请小心使用。当然,你随时可以通过按 Ctrl + C 来终止命令。

    注意:当指定文件夹的时候(例如示例中的"./test"文件夹),忽略末尾的斜杠是没有问题的。但是,如果文件夹是一个指向其它位置的链接(symlink)时,你必须在末尾写上斜杠才能使find命令正常工作(find ./test/)。

    忽略大小写

    在查找文件名时,忽略大小写往往非常有用。要忽略大小写,只需要使用 iname 选项,而不是 name 选项。

    $ find ./test -iname "*.Php"
    ./test/subdir/how.php
    ./test/cool.php
    
    

    总是用双引号或单引号来包围匹配模式(文件名参数),这非常有用。不这样做的话有时也能正常工作,有时也可能会产生奇怪的结果。

    3. 限制目录查找的深度

    find 命令默认会递归查找整个目录树,而这非常消耗时间和资源。好在目录查找的深度可以手动指定。例如我们只想查找一到两层以内的子目录,可以通过 maxdepth 选项来指定。

    $ find ./test -maxdepth 2 -name "*.php"
    ./test/subdir/how.php
    ./test/cool.php
    
    $ find ./test -maxdepth 1 -name *.php
    ./test/cool.php
    
    

    第二个示例中指定了 maxdepth 为1,表明最多只查找一层内的子目录,也就是只查找当前文件夹。

    当我们只想在当前目录下查找,而不是查找整个目录树的时候,这个选项会特别有用。

    与 maxdepth 选项相似,还有一个选项叫做 mindepth ,正如名字所表示的那样,它会至少到达第 N 层子目录后才开始查找文件。

    4. 反向查找

    除了查找满足条件的文件之外,我们还可以查找不满足条件的所有文件。当我们知道要在查找中排除哪些文件时,这个选项就能发挥作用了。

    $ find ./test -not -name "*.php"
    ./test
    ./test/abc.txt
    ./test/subdir
    
    

    在上面的示例中我们找到了所有扩展名不是 php 的文件和文件夹。我们也可以使用感叹号 ! 来代替 -not。

    find ./test ! -name "*.php"
    
    
    5. 结合多个查找条件

    我们可以同时使用多个查找条件来指定文件名并排除某些文件。

    $ find ./test -name 'abc*' ! -name '*.php'
    ./test/abc.txt
    ./test/abc
    
    

    上面的命令查找所有以 abc 开头并且不含 .php 扩展名的文件。这个示例展现了 find 命令自带的查找表达式是多么的强大。

    OR 操作符

    当我们使用多个查找条件时, find 命令会将它们通过 AND 操作符结合起来,也就是说,只有满足所有条件的文件才会被列出。不过,如果我们需要进行基于 OR 运算的查找时,可以加上 -o 开关。

    $ find -name '*.php' -o -name '*.txt'
    ./abc.txt
    ./subdir/how.php
    ./abc.php
    ./cool.php
    
    

    上面的命令查找所有以 .php 结尾或者以 .txt 结尾的文件。

    6. 只查找文件或目录

    有时我们只想通过某个名字查找对应的文件或对应的目录,我们可以很容易实现这个要求。

    $ find ./test -name abc*
    ./test/abc.txt
    ./test/abc
    
    

    只查找文件

    $ find ./test -type f -name "abc*"
    ./test/abc.txt
    
    

    只查找目录

    $ find ./test -type d -name "abc*"
    ./test/abc
    
    

    非常有用而且方便!

    7. 同时在多个目录下查找

    如果你想要在两个不同的目录内进行查找,命令非常简单。

    $ find ./test ./dir2 -type f -name "abc*"
    ./test/abc.txt
    ./dir2/abcdefg.txt
    
    

    检查一下,它确实列出了来自给定的两个目录的文件。

    8. 查找隐藏文件

    在Linux系统中,隐藏文件的名字以英文的句号开头,即 . 。所以要列出隐藏文件,只需加上简单的文件名过滤条件就行了。

    $ find ~ -type f -name ".*"
    
    

    二、基于文件权限和属性的查找

    9. 查找指定权限的文件

    通过指定 perm 选项,我们可以查找具有特定权限的文件。下面的示例中查找了所有具有 664 权限的文件。

    $ find . -type f -perm 664
    ./abc.txt
    ./subdir/how.php
    ./abc.php
    ./cool.php
    
    

    我们可以用这个命令来查找带有错误权限的文件,这些文件可能会产生安全问题。

    可以结合 反向查找 来进行权限检查。

    $ find . -type f ! -perm 777
    ./abc.txt
    ./subdir/how.php
    ./abc.php
    ./cool.php
    
    
    11. 查找只读文件
    $ find /etc -maxdepth 1 -perm /u=r
    /etc
    /etc/thunderbird
    /etc/brltty
    /etc/dkms
    /etc/phpmyadmin
    ... output truncated ...
    
    
    12. 查找可执行文件
    $ find /bin -maxdepth 2 -perm /a=x
    /bin
    /bin/preseed_command
    /bin/mount
    /bin/zfgrep
    /bin/tempfile
    ... output truncated ...
    
    

    三、基于文件拥有者和用户组的查找

    13. 查找属于特定用户的文件

    查找当前目录下,属于 bob 的文件。

    $ find . -user bob
    .
    ./abc.txt
    ./abc
    ./subdir
    ./subdir/how.php
    ./abc.php
    
    

    在指定所属用户的同时,我们同样可以指定文件名。

    $ find . -user bob -name '*.php'
    
    

    很容易看出,我们可以通过增加过滤条件来缩小查找文件的范围。

    14. 查找属于特定用户组的文件
    # find /var/www -group developer
    
    

    四、基于日期和时间的查找

    除了上面介绍的查找条件外,另外一个非常棒的查找条件就是文件的修改和访问时间(日期)。当我们想要找出哪些文件在某段时间内被修改的时候,这个查找条件将会非常方便。我们来看几个例子。

    15. 查找过去的第 N 天被修改过的文件
    # find / -mtime 50
    
    
    16. 查找过去的 N 天内被访问过的文件
    # find / -atime -50
    
    
    17. 查找某段时间范围内被修改过内容的文件
    # find / -mtime +50 -mtime -100
    
    
    18. 查找过去的 N 分钟内状态发生改变的文件
    $ find /home/bob -cmin -60
    
    
    19. 查找过去的 1 小时内被修改过内容的文件
    # find / -mmin -60
    
    
    20. 查找过去的 1 小时内被访问过的文件
    # find / -amin -60
    
    

    五、基于文件大小的查找

    21. 查找指定大小的文件
    $ find / -size 50M
    
    
    22. 查找大小在一定范围内的文件
    $ find / -size +50M -size -100M
    
    
    23. 查找最大和最小的文件

    我们可以将 find 命令与 ls 和 sort命令结合,从而找出最大或最小的文件。

    下面的命令使用了 sort 命令的 -r 选项,也就是从大到小降序排列。经过 head 命令的过滤之后,会显示当前目录和子目录下最大的5个文件。命令的执行过程需要一段时间,查找的速度取决于文件的总数。

    $ find . -type f -exec ls -s {} \; | sort -n -r | head 5
    
    

    同样,我们可以去掉 sort 命令的 -r 选项来进行升序排列,从而显示出最小的5个文件。

    $ find . -type f -exec ls -s {} \; | sort -n | head 5
    
    
    24. 查找空文件和空目录

    查找空文件:

    # find /tmp -type f -empty
    
    

    查找空目录:

    $ find ~/ -type d -empty
    
    

    非常简单!

    六、高级操作

    find 命令不仅可以通过特定条件来查找文件,还可以对查找到的文件使用任意linux命令进行操作。下面给出两个例子。

    25. 使用 ls 命令列出文件信息

    我们使用 find 命令找到文件后,只能看到文件路径。如果想进一步查看文件信息,可以结合 ls 命令来实现。

    $ find . -exec ls -ld {} \;
    drwxrwxr-x 4 enlightened enlightened 4096 Aug 11 19:01 .
    -rw-rw-r-- 1 enlightened enlightened 0 Aug 11 16:25 ./abc.txt
    drwxrwxr-x 2 enlightened enlightened 4096 Aug 11 16:48 ./abc
    drwxrwxr-x 2 enlightened enlightened 4096 Aug 11 16:26 ./subdir
    -rw-rw-r-- 1 enlightened enlightened 0 Aug 11 16:26 ./subdir/how.php
    -rw-rw-r-- 1 enlightened enlightened 29 Aug 11 19:13 ./abc.php
    -rw-rw-r-- 1 enlightened enlightened 0 Aug 11 16:25 ./cool.php
    
    

    -exec是执行的意思,{}是find的搜寻结果,;是转义分号,不让shell去解释,因为这个分号是给-exec用的.

    26. 删除找到的文件

    下面的命令会删除 tmp 目录下扩展名为 .txt 的文件。

    $ find /tmp -type f -name "*.txt" -exec rm -f {} \;
    
    

    我们同样可以删除目录,只要把 -type 后面的 f 改为 d ,并且在 rm 命令后面加上 -r 即可。

    $ find /tmp -type d -name "dirToRemove" -exec rm -r -f {} \;
    
    

    原文来自:http://www.codebelief.com/article/2017/02/26-examples-of-find-command-on-linux/

    补充Find命令搭配atime/ctime/mtime时的日期写法

    find可谓是aix/linux上使用较多的维护用命令,但很多时候需要用到针对时间的搜索。本文主要对find中搭配atime、ctime和mtime的各种参数进行介绍。
    atime:访问时间(access time),指的是文件最后被读取的时间,可以使用touch命令更改为当前时间;
    ctime:变更时间(change time),指的是文件本身最后被变更的时间,变更动作可以使chmod、chgrp、mv等等;
    mtime:修改时间(modify time),指的是文件内容最后被修改的时间,修改动作可以使echo重定向、vi等等;

    以下例子应该很容易理解上述三个时间:某用户在2013年1月5日00:00:00时,在/home下输入ping www.baidu.com > ping.log;5秒钟后,该用户使用ctrl+C强制关闭该命令;5秒钟后,使用cat ping.log查看。则ping.log的ctime为2013-01-05 00:00:00;mtime为2013-01-05 00:00:05;atime为2013-01-05 00:00:10。

    这三个参数理解后,我们就可以使用find找到某个时刻进行过某类操作的文件集合。

    find . {-atime/-ctime/-mtime/-amin/-cmin/-mmin} [-/+]num
    第一个参数,.,代表当前目录,如果是其他目录,可以输入绝对目录和相对目录位置;
    第二个参数分两部分,前面字母a、c、m分别代表访问、变更、修改,后面time为日期,min为分钟,注意只能以这两个作为单位;
    第三个参数为量,其中不带符号表示符合该数量的,带-表示符合该数量以后的,带+表示符合该数量以前的。

    举例

    找出 3 天"以前"被改动过的文件 (前第三天以前 → 2011/09/05 12:00 以前的文件) (> 72 小时)

    find /var/log/ -mtime +3 -type f -print
    找出 3 天內被改动过的文件 (2011/09/05 12:00 ~ 2011/09/08 12:00 內的文件) (0 ~ 72 小时內)

    find /var/log/ -mtime -3 -type f -print
    找出前第 3 天被改动过的文件 (2011/09/04 12:00 ~ 2011/09/05 12:00 內的文件) (72 ~ 96 小时)

    find /var/log/ -mtime 3 -type f -print
    找出第 3 天被改动过的文件 (也可以这样写)

    find /var/log/ -mtime +2 -mtime -4 -type f -print

    touch命令修改文件时间

    创建文件我们可以通过touch来创建。同样,我们也可以使用touch来修改文件时间。touch的相关参数如下:

    -a : 仅修改access time。
    -c : 仅修改时间,而不建立文件。
    -d : 后面可以接日期,也可以使用 --date="日期或时间"
    -m : 仅修改mtime。
    -t : 后面可以接时间,格式为 [YYMMDDhhmm]
    注:如果touch后面接一个已经存在的文件,则该文件的3个时间(atime/ctime/mtime)都会更新为当前时间。若该文件不存在,则会主动建立一个新的空文件

    查看文件详情

    stat filename

    补充 find -exec

    find 是我们很常用的一个Linux命令,但是我们一般查找出来的额并不仅仅是看看而已,还会有进一步的操作,这个时候exec的作用就显现出来了。

    exec解释:

    -exec 参数后面跟的是 command 命令,它的终止是以“;”为结束标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面加反斜杠。

    {} 花括号代表前面find查找出来的文件名。

    使用find时,只要把想要的操作写在一个文件里,就可以用exec来配合find 查找,很方便的。在有些操作系统中,只允许 -exec 选项执行诸如 ls 或 ls -l 这样的命令。大多数用户使用着一些选项是为了查找旧文件并删除它们。建议再真正执行 rm 命令删除文件之前,最好先用 ls 命令看一下,确认他们是所要删除的文件。 exec 选项后面跟随着所要执行的命令或脚本,然后是一对儿{},一个空格和一个\,最后是一个分号。为了使用 exec 选项,必须要同时使用 print 选项。如果验证一下 find 命令,会发现该命令只输出从当前路径起的相对路径及文件名。

    实例1:ls -l 命令放在 find 命令的 -exec 选项中

    命令:

    find . -type f -exec ls -l {} ;   find 命令匹配到了当前目录下的所有普通文件,并在 -exec 选项中使用 ls -l 命令将它们列出。

    这个命令有点坑,不过确实很好用,说它坑是因为我输入的时候 收到提示:find 遗漏 -exec 的参数,^^

    解决:1.注意 是一对儿{},一个空格和一个\,最后是一个分号

    2.  在 ; 使用 “;” ';' 这样把它们引起来。【“引起来”,感觉怪别扭的,不过想不出来怎么描述】

    实例2:在目录中查找更改时间在n 日以前的文件并删除它们

    命令:

    find . -type f -mtime +14 -exec rm {} ; 在 shell 中用任何方式删除文件之前,应当先查看相应的文件,一定要小心,当使用诸如 mv 或 rm 命令时,

    可以使用-exec 选项的安全模式,他将对每个匹配到的文件进行操作之前提示你。

    实例3:在目录中查找更改时间在n日以前的文件并删除它们,在删除之前先给出提示

    命令:

    find . -name "*.log" -mtime +5 -ok rm {} ; 查找当前目录中所有以 .log 结尾的,更改时间在 5 日以上的文件,并删除它们,并且在删除之前先给出提示。按y 键确定,n 键 取消。

    实例4: -exec 中使用 grep 命令

    命令:

    find /etc -name "passwd" -exec grep "root" {} ;

    任何形式的命令都可以在 -exec 选项中使用。 在上面的例子中我们使用 grep 命令。find命令首先匹配所有文件名为“passwd”的文件,然后执行 grep 命令查看这些文件中是否存在一个 root 用户。

    实例5:查找文件并移动到指定目录

    命令:

    find . -name "*.log" -exec mv {} .. ;    .. 是路径名

    实例6:用exec选项执行 cp 命令

    命令:

    find . -name "*.log" -exec cp {} test3 ;   一不小心又中招了,test3 是个目录,不然cp 不进去。

    相关文章

      网友评论

        本文标题:第二十二课 Linux系统中的 find 命令

        本文链接:https://www.haomeiwen.com/subject/vpiawftx.html