find
在目录结构中搜索文件,并执行指定的操作。find 命令提供了相当多的查找条件,功能很强大。
语法:find [起始目录] 寻找条件 操作
find path -options[-print][-exec][-ok][...]
- path,表示find命令所查找的目录,比如用.来表示当前目录,用/来表示系统根目录;
- -print,表示将查找到的文件输出到标准输出,如果没有指定,默认是该模式;
- -exec,对查找到的文件执行该参数所给出的shell命令,相应命令的形式为
'command' {} ;
,注意 {} 和 \; 之间的空格; - -ok,和-exec选项功能类似,但该选项更安全,在执行每一个命令之前,都会给出提示,让用户来确定是否执行;
1. 基本用法
find命令从指定的起始目录开始,递归地搜索其各个子目录,查找满足寻找条件的文件并对之采取相关的操作。 该命令提供的寻找条件可以是一个用逻辑运算符 not、and、or 组成的复合条件。
and:逻辑与,在命令中用"-a"表示,是系统缺省的选项,表示只有当所给的条件都满足时,寻找条件才算满足。
例如:
find . –name 'tmp' –xtype c -user 'inin'
该命令寻找三个给定条件都满足的所有文件
or:逻辑或,在命令中用"-o"表示。该运算符表示只要所给的条件中有一个满足时,寻找条件就算满足。
例如:
find / –name 'tmp' –o –name 'mina*'
该命令查询文件名为'tmp'或是匹配'mina*'的所有文件。
not:逻辑非,在命令中用"!"表示。该运算符表示查找不满足所给条件的文件 。
例如:
find ! –name 'tmp'
该命令查询文件名不是'tmp'的所有文件。
需要说明的是:当使用很多的逻辑选项时,可以用括号把这些选项括起来。为了避免She ll本身对括号引起误解,在话号前需要加转义字符"\"来去除括号的意义。
例:
find \( –name 'tmp' –xtype c -user 'inin' \)
该命令的各选项含义如下:
n 值可以有三种输入方式,假设 n 为20,则:
+20 表示20以后(21,22,23等) -20 表示20以前(19,18,17等) 20 表示正好是20
以名称和文件属性查找。
-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. 例子
查找当前目录中所有以main开头的文件,并显示这些文件的内容。
find . -name 'main*' -exec more {} ;
删除当前目录下所有一周之内没有被访问过的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 {} \;
- 其中 {} 代表当前查到的符合条件的文件名,\;则是语法所要求的。
- 上述命令中第一行的最后一个 \ 是续行符。当命令太长而在一行写不下时,可输入一个 \,之后系统将显示一个 >,指示用户继续输入命令。
- 是否在7天以前(条件 -atime +7),若是,则对该文件执行rm命令
- 查找/logs目录下权限为 644的文件
在使用八进制查询的时候,可以在八进制数字前面加一个横杠 -,表示都匹配,如-007就相当于777,-005相当于555;find /log -perm 644
- 查找当目录以.log结尾的普通文件
find . -type f -name "*.log"
- 查找当前所有目录并排序
find . -type d | sort
- 查找当前目录大于1k的文件
大于与小与的查询是可以同时使用的,如 查询 文件大小大于2M小于10M的find . -size +1000c -print
find . -size +2M -size -10M -print
- 在/目录下查找/start开头并且以end结尾的文件
find / -path "/start*end"
- 如果在查找文件时希望忽略某个目录,可以使用-prune选项,但使用的时候需要注意下,因为如果同时使用了-depth选项,那么-prune选项就会被find命令忽略,如果希望在test目录下查找文件,但不希望在test/test3目录下查找,可以使用:
借助-printf 来打印查找到的文件的相应属性,比如时间,大小find test -path "test/test3" -prune -o -print
find -type f -printf '%T+%p \n'
- 多个文件查找某个关键字: 在所有 properties 文件中查找
tlsv1
方式1: cat | grep
方式2: find | xargs grepcat *.properties | grep 'tlsv1'
find . -maxdepth 5 -type f -name "*.properties" | xargs grep -i 'tlsv1'
3. exec 与ok 模式
如果只是查找的话,上面的这些查询已经够我们平时用了,不过我们有时候不仅仅是只查找一下,可能还会有后缀的操作,这个时候就要使用-exec模式了。
-exec后面跟的是shell命令,表示查询出对应的文件后进行其他命令操作。该模式结束是以 ; 为标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面会加反斜杠。
该命令格式一般为:
find path -exec command {} \;
首先是exec选项,后面是要执行的命令或脚本,然后是一对{ },一个空格和一个\,最后是一个分号。其中花括号代表前面find查找出来的文件名;
查看并列出对应文件
find . -type f -exec ls -l {} \;
查找并删除修改时间在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
查找文件并查找文件中的内容
find /test -name "passwd*" -exec grep "root" {} \;
首先查找所有文件名以“passwd”开头的文件,然后执行grep命令看看在这些文件中是否存在一个root用户。
查找并复制文件到指定目录
find . -name "*.log" -exec cp {} test3 \;