美文网首页
find:文件查找命令

find:文件查找命令

作者: dshowing | 来源:发表于2019-05-26 13:01 被阅读0次

    Linux find命令用来在指定目录下查找文件。
    find命令功能强大,选项比较多,能够记住的选项就那么几个,正好通过这次好好整理一下(不是全部,仅常用选项);查阅文档的时候对pathname前的几个选项一直不是很清楚,不知为何网上的帖子大都没有涉及到这部分,本篇参考了‘远有青山’的文章

    用法:

    #find [-H] [-L] [-P] [-Olevel] [-D debugopts] [path...] [expression]
    

    通常情况下find命令使用忽略掉pathname前的选项就可以

    #find pathname -options [-print] [-exec -ok command] {} \;
    

    其中-H -L -P选项主要负责符号链接的处理:

    • -H 表示只跟随命令行中指定的符号链接
    • -L 表示跟随所有的符号链接
    • -P 是默认的选项,表示不跟随任何符号链接,也就是说-P 选项可以不加
    • -D 为调试选项,配合相关选项打印出调试信息;
    • -O 针对查询顺序等因素,使用不同级别优化查询过程

    E.g.
    如果当前目录下有一个符号链接a123,想在想要查找文件名最后一位是数字的文件,那么下面两种将不会显示a123的结果:

    #find . -name "*[0-9]" -print
    #find -H . -name "*[0-9]" -print
    

    如果需要找出符号链接a123,可以这么写:

    #find -H a123 . -name "*[0-9]" -print
    #find -L . -name "*[0-9]" -print
    

    find选项:

    pathname部分指定了使用者查询的原始路径,而且此路径和后续表达式一定要置于-D -H -L -P -O这些选项的后边
    命令中的[expression]是匹配项表达式。根据man手册提供的信息,表达式可分为三部分:

    • option 设置项
    • test 测试项
    • action 动作项

    三部分结合使用,就体现出了find命令的强大所在。

    Option

    设置项的一些选项针对此次查找任务,而不是针对文件进行配置,返回值总是True。

    • -depth 查找文件时,先查找指定目录中的文件,而后查找其子目录。(Tests类中也有此选项,目前不太清楚怎么回事)
    • -maxdepth 限定搜索目录的深度
    • -mindepth 限定搜索目录的深度
    • -follow 跟踪链接文件,找到原文件
    • -mount 不跨越挂载点进行查找
    • -version 打印版本号并退出
    • -help 打印常规用法并退出

    maxdepth/mindepth
    限定查询深度:

    • maxdepth 指最大不超过几层目录;[0,n]
    • mindepth 指最小不超过几层目录;[n,无限深度]

    规定当前目录为第一层深度。
    在家目录下2层深度查找123:

    #find /home/dshowing/ -maxdepth 2 -name 123
    /home/dshowing/123
    /home/dshowing/test/123
    

    在家目录下3层深度查找123:

    #find /home/dshowing/ -maxdepth 3 -name 123
    /home/dshowing/123
    /home/dshowing/test/123
    /home/dshowing/test/abc/123
    

    在家目录第二层和第三层目录之间查找123:

    #find /home/dshowing/ -mindepth 2 -maxdepth 3 -name 123
    /home/dshowing/test/123
    /home/dshowing/test/abc/123
    

    Tests

    测试项是针对具体文件进行匹配测试,常见有-name -type等选项,返回值为True或False。

    • -name 按照文件名进行查找
    • -perm 按照文件权限进行查找
    • -prune 这一选项可以使find不在当前指定的目录中进行查找,如果同时出现-depth选项,此选项则被忽略
    • -user 按照文件所属主进行查找
    • -nouser 查找无有效属主的文件,即所属主不在/etc/password文件中
    • -group 按照文件所属组进行查找
    • -nogroup 查找无有效属组的文件,即所属组不在/etc/groups文件中
    • -newer A !B 查找更改时间比文件A新但是比文件B文件旧的文件
    • -type 查找某一类型的文件,其中有:
      • b 块设备文件
      • d 目录
      • c 字符设备文件
      • p 管道文件
      • l 符号链接文件
      • f 普通文件
    • -size n[c] 查找文件长度为n块的文件,带c时表示文件大小以字节计
    • -mtime n/-n/+n 按照文件的更改时间进行匹配,-n表示更改时间距现在n天以内,+n表示文件更改时间已经超过n天
    • -atime n/-n/+n 参照文件被读取或执行的时间进行匹配
    • -ctime n/-n/+n 参照文件状态被改变的时间进行匹配
    • -depth 查找文件时,先查找当前目录的文件,再在其子目录中进行查找
    • -mount 查找文件时,不跨越文件系统的挂载点
    • -follow 如果查询时匹配到了链接文件,那么跟踪至所指向的原文件
    • -cpio 对匹配的文件使用cpio命令,将这些文件备份到磁带设备中

    -name
    文件名匹配是使用次数最多的匹配方式,使用通配符匹配,查找小写字母开头数字结尾的TXT文件:

    #find /opt/ -name "[a-z]*[0-9].txt" -print
    

    -print是缺省选项,可不加

    -perm
    按照文件权限进行匹配,通常使用8进制的权限表示法,别的我没试过,平常几乎不用。根目录查找仅属主有读权限的文件:

    #find / -perm 400
    

    -prune
    如果在查找过程中希望忽略某个目录,那么可以使用-prune选项来指定;但是如果在设置项中同时指定了-depth选项,则此选项无效,将被忽略。
    根目录下查找文件,跳过/home目录:

    #find / "/home/" -prune -name -o -print
    

    user/nouser
    查找指定用户文件/无有效用户文件:

    #find / -user nginx -print
    #find / -nouser -print
    

    group/nogroup
    类似于user和nouser选项:

    #find / -group workterm -print
    #find / -nogroup -print
    

    newer
    如果能够确定两个文件的大体更改时间,并想查找处于这段时间内的文件,可以使用-newer选项;其中!为逻辑非符号,一般格式为:
    find pathname -newer older_filename ! newer_filename -print
    列出更改时间比older_filename文件新,但比newer_filename文件旧的文件:

    #find /home/ -newer older_filename ! newer_filename -exec ls -lh {} \;
    

    查找比123.log文件新的(更改时间晚于123.log)的文件:

    #find /home/ -newer 123.log -exec ls -lh {} \;
    

    mtime/ctime/atime
    三种时间针对文件或目录的三种不同的时间属性:

    • mtime (modify time)文件内容更改时间
    • ctime (change time)文件状态更改时间
    • atime (access time)文件被读取或执行的时间

    选项参数中的n指的是n*24h,需要注意的是对时间范围的界定:

    • find . -mtime n 指的是更改时间距今n24小时至(n+1)24小时,包含n24小时;[n24h,(n+1)*24h)
    • find . -mtime +n 指定是更改时间距今(n+1)24小时甚至更早; [(n+1)24h,正无穷)
    • find . -mtime -n 指定是文件更改发生在n24小时以内; [0,n24h)

    type
    Unix和Linux系统中有多种文件类型,查找家目录中所有目录:

    #find /home/dshowing/ -type d -print
    

    查找当前目录中非目录文件:

    #find . ! -type d -print
    

    size
    size选项按照文件长度(大小)进行匹配。
    使用-size n/+n/-n [bcwkMG]来限定文件的大小:

    • b 单位为块,512字节为一块(缺省,不加单位时默认为块大小)
    • c 字节大小
    • w 字大小,1字=2字节
    • k 千字节,kB
    • M 兆字节,MB
    • G 千兆字节,GB

    1Byte=8bit

    depth
    使用此选项,现在指定目录中查找,而后再在其子目录中进行查找。先查找根目录,而后在子目录中查找:

    #find / -name "123.txt" -depth -print
    

    mount
    仅在当前文件系统中查找,而不跨越到挂载点的其他系统文件:

    #find . -name "123.txt" -mount -print
    

    cpio
    使用cpio选项可以在查找文件时将文件备份到磁带设备中,或将其恢复;平时几乎不使用,不做深究。

    Action

    动作选项决定对查找的文件作出具体操作。

    • -delete 删除文件
    • -print 在新行中,将查询结果显示在标准输出中
    • -printf [format] 格式化输出,显示到标准输出
      • \a 响铃
      • \b 空格
      • \n 回车换行
      • \t 打印制表符
    • -exec 执行命令操作
    • -ok 分布执行命令操作

    执行命令的一般格式为:-exec 'command' {} \; ,注意花括号后的空格
    查找家目录中,文件大小大于100M,更改时间超过5天的文件,删除之:

    #find /home/dshowing/ -size +100M -mtime +5 -exec rm -r {} \;
    

    不建议在查找命令中直接使用删除操作,先确认再删除,减少心脏病发病的风险

    如果非要这样,不如使用-ok 'command' {} \;命令,相比于exec,它对文件的每一次执行都会在命令行中交互,每一步都需要确认:

    #find / -size +100M -mtime +5 -ok rm -r {} \;
    

    xargs和find

    在find命令查找完成后,如果需要执行一些操作的时候,系统会限制传给-exec选项的命令长度,如果命令参数过长,执行途中会报溢出错误。此时就可以用xargs命令:

    find /home/dshowing/ -size +100M -mtime +5 | xargs rm -rf
    

    此外,使用find命令查找完成后,还可以使用管道符传送给之后的执行命令,这根使用xargs有些区别:

    # pwd
    /root/
    # echo 123456 > test.txt
    # find . -name *.txt
    ./test.txt
    # find . -name *.txt | cat
    ./test.txt
    # find . -name *.txt | xargs cat
    123456
    

    对于两种不同的输出,网友给出的解释是:

    管道是实现:将前面的标准输出作为后面的标准输入;
    xargs是实现:将前面的标准输出作为后一条命令的参数

    牛平举了个“一切皆文件”的例子,感觉很形象:

    # echo --help | cat
    --help
    # echo --help | xargs cat
    Usage: cat [OPTION]... [FILE]...
    Concatenate FILE(s), or standard input, to standard output.
    ...
    ...
    ...
    Examples:
     cat f - g  Output f's contents, then standard input, then g's contents.
     cat        Copy standard input to standard output.
    ..
    ..
    

    第一次,将--help赋给了管道符,而后cat命令显示管道符内容;
    第二次通过xargs,将--help从管道符中读取出来,作为了cat命令的直接参数,输出的也就是help文档了。

    More info: Click

    相关文章

      网友评论

          本文标题:find:文件查找命令

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