find

在目录结构中搜索文件,并执行指定的操作。find 命令提供了相当多的查找条件,功能很强大。

语法:find [起始目录] 寻找条件 操作
find path -options[-print][-exec][-ok][...]
  • path,表示find命令所查找的目录,比如用.来表示当前目录,用/来表示系统根目录;
  • -print,表示将查找到的文件输出到标准输出,如果没有指定,默认是该模式;
  • -exec,对查找到的文件执行该参数所给出的shell命令,相应命令的形式为 'command' {} ; ,注意 {} 和 \; 之间的空格;
  • -ok,和-exec选项功能类似,但该选项更安全,在执行每一个命令之前,都会给出提示,让用户来确定是否执行;

1. 基本用法

find命令从指定的起始目录开始,递归地搜索其各个子目录,查找满足寻找条件的文件并对之采取相关的操作。 该命令提供的寻找条件可以是一个用逻辑运算符 not、and、or 组成的复合条件。

  1. and:逻辑与,在命令中用"-a"表示,是系统缺省的选项,表示只有当所给的条件都满足时,寻找条件才算满足。

    例如:

     find . –name 'tmp' –xtype c -user 'inin'
    

    该命令寻找三个给定条件都满足的所有文件

  2. or:逻辑或,在命令中用"-o"表示。该运算符表示只要所给的条件中有一个满足时,寻找条件就算满足。

    例如:

     find / –name 'tmp' –o –name 'mina*'
    

    该命令查询文件名为'tmp'或是匹配'mina*'的所有文件。

  3. not:逻辑非,在命令中用"!"表示。该运算符表示查找不满足所给条件的文件 。

    例如:

     find ! –name 'tmp'
    

    该命令查询文件名不是'tmp'的所有文件。

    需要说明的是:当使用很多的逻辑选项时,可以用括号把这些选项括起来。为了避免She ll本身对括号引起误解,在话号前需要加转义字符"\"来去除括号的意义。

    例:

     find \( –name 'tmp' –xtype c -user 'inin' \)
    

    该命令的各选项含义如下:

  4. n 值可以有三种输入方式,假设 n 为20,则:

     +20 表示20以后(21,22,23等)
     -20 表示20以前(19,18,17等)
     20 表示正好是20
    
  5. 以名称和文件属性查找。

     -name '字串' 查找文件名匹配所给字串的所有文件,字串内可用通配符 *、?、[ ]。
     -iname  按照文件名查找,但会忽略大小写;
     -lname '字串' 查找文件名匹配所给字串的所有符号链接文件,字串内可用通配符 *、?、[ ]。
     -gid n 查找属于ID号为 n 的用户组的所有文件。
     -uid n 查找属于ID号为 n 的用户的所有文件。
     -group '字串' 查找属于用户组名为所给字串的所有的文件。
     -user '字串' 查找属于用户名为所给字串的所有的文件。
     -empty 查找大小为 0的目录或文件。
     -path '字串' 查找路径名匹配所给字串的所有文件,字串内可用通配符*、?、[ ]。
     -perm 权限 查找具有指定权限的文件和目录,权限的表示可以如711,644。
     -prune  查找时忽略某目录;
     -size n[bckw] 查找指定文件大小的文件,n 后面的字符表示单位,缺省为 b,代表512字节的块。
         c 以字节单位;
         b 以块为单位,其中块大小为512字节,这个是默认单位;
         w 以words为单位,words表示两个字节;
         k 以1024字节为单位,也就是kilo bytes,kb;
         M-类似,以1024*1024字节为单位,也就是Mb;
         G-Gb;
    
     -type x 查找类型为 x 的文件,x 为下列字符之一:
         b 块设备文件
         c 字符设备文件
         d 目录文件
         p 命名管道(FIFO)
         f 普通文件
         l 符号链接文件(symbolic links)
         s socket文件
         -xtype x 与 -type 基本相同,但只查找符号链接文件。
     以时间为条件查找
     -amin n 查找n分钟以前被访问过的所有文件。
     -atime n 查找n天以前被访问过的所有文件。
     -cmin n 查找n分钟以前文件状态被修改过的所有文件。
     -ctime n 查找n天以前文件状态被修改过的所有文件。
     -mmin n 查找n分钟以前文件内容被修改过的所有文件。
     -mtime n 查找n天以前文件内容被修改过的所有文件。
    
     可执行的操作
     -exec 命令名称 {} 对符合条件的文件执行所给的Linux 命令,而不询问用户是否需要执行该命令。
     {}表示命令的参数即为所找到的文件;命令的末尾必须以" \;"结束。
     -ok 命令名称 {} 对符合条件的文件执行所给的Linux 命令,与exec不同的是,它会询问用户是否需要执行该命令。
     -ls 详细列出所找到的所有文件。
     -fprintf 文件名 将找到的文件名写入指定文件。
     -print 在标准输出设备上显示查找出的文件名。
     -printf 格式 格式的写法请参考有关C语言的书。
    

    前缀+-,和时间是同一个意思,加号表示查找大于给定长度的文件,减号则是表示查找小于给定长度的文件;

2. 例子

  1. 查找当前目录中所有以main开头的文件,并显示这些文件的内容。

     find . -name 'main*' -exec more {} ;
    
  2. 删除当前目录下所有一周之内没有被访问过的a .out或*.o文件。

     find . \( -name a.out -o -name '*.o' \) -atime +7 -exec rm {} \;
    
    • 命令中的"."表示当前目录,此时 find 将从当前目录开始,逐个在其子目录中查找满足后面指定条件的文件。
    • "(" 和 ")" 表示括号(),其中的 "\" 称为转义符。之所以这样写是由于对 Shell 而言,(和)另有不同的含义,而不是这里的用于组合条件的用途。注意: "(" 和 ")"两遍要加空格
    • -name a.out 是指要查找名为a.out的文件;
    • -name '*.o' 是指要查找所有名字以 .o 结尾的文件。
    • 两个 -name 之间的 -o 表示逻辑或(or),即查找名字为a.out或名字以 .o结尾的文件。
    • find在当前目录及其子目录下找到这样的文件之后,再进行判断,看其最后访问时间
      • 是否在7天以前(条件 -atime +7),若是,则对该文件执行rm命令 -exec rm {} \;
      • 其中 {} 代表当前查到的符合条件的文件名,\;则是语法所要求的。
      • 上述命令中第一行的最后一个 \ 是续行符。当命令太长而在一行写不下时,可输入一个 \,之后系统将显示一个 >,指示用户继续输入命令。
  3. 查找/logs目录下权限为 644的文件
     find /log -perm 644
    
    在使用八进制查询的时候,可以在八进制数字前面加一个横杠 -,表示都匹配,如-007就相当于777,-005相当于555;
  4. 查找当目录以.log结尾的普通文件
     find . -type f -name "*.log"
    
  5. 查找当前所有目录并排序
     find . -type d | sort
    
  6. 查找当前目录大于1k的文件
     find . -size +1000c -print
    
    大于与小与的查询是可以同时使用的,如 查询 文件大小大于2M小于10M的
     find . -size +2M -size -10M -print
    
  7. 在/目录下查找/start开头并且以end结尾的文件
     find / -path "/start*end"
    
  8. 如果在查找文件时希望忽略某个目录,可以使用-prune选项,但使用的时候需要注意下,因为如果同时使用了-depth选项,那么-prune选项就会被find命令忽略,如果希望在test目录下查找文件,但不希望在test/test3目录下查找,可以使用:
     find test -path "test/test3" -prune -o -print
    
    借助-printf 来打印查找到的文件的相应属性,比如时间,大小
     find -type f -printf '%T+%p \n'
    
  9. 多个文件查找某个关键字: 在所有 properties 文件中查找 tlsv1
    方式1: cat | grep
     cat *.properties | grep 'tlsv1'
    
    方式2: find | xargs grep
     find . -maxdepth 5 -type f -name "*.properties" | xargs grep -i 'tlsv1'
    

3. exec 与ok 模式

如果只是查找的话,上面的这些查询已经够我们平时用了,不过我们有时候不仅仅是只查找一下,可能还会有后缀的操作,这个时候就要使用-exec模式了。

-exec后面跟的是shell命令,表示查询出对应的文件后进行其他命令操作。该模式结束是以 ; 为标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面会加反斜杠。

该命令格式一般为:

find path -exec command {} \;

首先是exec选项,后面是要执行的命令或脚本,然后是一对{ },一个空格和一个\,最后是一个分号。其中花括号代表前面find查找出来的文件名;

  1. 查看并列出对应文件

     find . -type f -exec ls -l {} \;
    
  2. 查找并删除修改时间在2天以前的文件

     find . -type f -mtime +2 -exec rm {} \;
    

    在任何删除之前,都应该先查看相应的文件,以免进行误删除操作;而 -ok 选项则可以看作是exec的安全模式,它会在删除前提示你进行确认:

     master@127.0.0.1:/logs$ find . -name "*.log" -ok rm {} \; 
     < rm ... ./test2.log > ? y
    
  3. 查找文件并查找文件中的内容

     find /test -name "passwd*" -exec grep "root" {} \;
    

    首先查找所有文件名以“passwd”开头的文件,然后执行grep命令看看在这些文件中是否存在一个root用户。

  4. 查找并复制文件到指定目录

     find . -name "*.log" -exec cp {} test3 \;
    

results matching ""

    No results matching ""