介绍
find 可以查找文件
具有包含特定文本或与特定模式匹配的名称;
是指向某些文件的链接;
在一段时间内最后一次使用
在一定尺寸范围内
属于特定类型(常规文件、目录、符号链接等)
由特定用户或组拥有;
具有某些访问权限或特殊模式位;
包含与特定模式匹配的文本;
在目录树中的一定深度内;
或上述内容的某种组合。
查找到之后可以对这些文件进行操作
查看或编辑
存档中的存储
删除或重命名
更改访问权限
分类为组
使用概述
find搜索目录层次结构中的文件并打印有关找到的文件的信息。它的运行方式如下:
find [file…] [expression]
expression有四个元素组成: operators, options, tests, and actions
每个元素都是 的单独命令行参数。
-
options
影响整体操作,而不是特定文件的处理;
-depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf --version -xdev -ignore_readdir_race -noignore_readdir_race
-
test
返回真值或假值,具体取决于文件的属性;
-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 ;
-
oprators
连接其他参数,并决定它们何时或是否被执行。
( EXPR ) ! EXPR -not EXPR EXPR1 -a EXPR2 EXPR1 -and EXPR2 EXPR1 -o EXPR2 EXPR1 -or EXPR2 EXPR1 , EXPR2
(expr) #优先级最高。为防止括号被shell解释(进入子shell),所以需要转义,即\(...\)
! expr #对expr的true和false结果取反。同样需要使用引号包围
-not expr #等价于"! expr"
expr1 expr2 #等同于and操作符。
expr1 -a expr2 #等同于and操作符。
expr1 -and expr2 #首先要求expr1为true,然后expr2以expr1搜索的结果为基础继续检测,然后再返回检测值为true的文件。因为expr2是以expr1结果为基础的,所以如果expr1返回
#false,则expr2直接被忽略而不会进行任何操作
expr1 -o expr2 #等同于or操作符
expr1 -or expr2 #只有expr1为假时才评估expr2。
expr1 , expr2 #逗号操作符表示列表的意思,expr1和expr2都会被评估,但expr1的true或false是被无视的,只有expr2的结果才是最终状态值。
使用
GNU 根据运算符优先级规则,通过从左到右执行给定表达式来搜索根植于每个给定起点的目录树,直到结果已知,此时移动到下一个文件名
起点默认为当前目录
options
options总是返回true。除了"-daystart",options会影响所有指定的test表达式部分,哪怕是test部分写在options的前面。这是因为options是在命令行被解析完后立即处理的,而test是在检测到文件后才处理的。对于"-daystart"这个选项,它们仅仅影响写在它们后面的test部分,因此,建议将任何options部分写在expression的最前面。
-daystart #指定以每天的开始(凌晨零点)计算关于天的时间,用于改变时间类(-amin,-atime,-cmin,-ctime,-mmin和-mtime)
#的计算方式。默认天的计算是从24小时前计算的。例如,当前时间为5月3日17:00,要求搜索出2天内修改过的文件,默认
#搜索文件的起点是5月1日17:00,如果使用-daystart,则搜索文件的起点是是5月1日00:00。
#注意,该选项只会影响写在它后面的test表达式。
-depth #搜索到目录时,先处理目录中的文件(子目录),再处理目录本身。对于"-delete"这个action,它隐含"-depth"选项。
-maxdepth levels #指定tests和actions作用的最大目录深度,只能为非负整数。可以简单理解为目录搜索深度,但并非如此。当
#前path目录的层次为1,所以若指定-maxdepth 0将得不到任何结果。
-mindepth levels #tests和actions不会应用于小于指定深度的目录,"-mindepth 1"表示应用于所有的文件。
-ignore_readdir_race #当无法用stat检测文件信息时(如无权限)会给出下图所示的错误信息,如要忽略该信息,可以使用该选项。
test
类型判断
-type [bcdpflsD] #查是块设备、字符设备、目录、管道、普通文件、符号链接,套接字文件
大小判断
-size N[bcwkMG]
b #512字节的(默认单位)
c #1字节的
w #2字节
k #1024字节
M #1024k
G #1024M
从文件名/路径名判断
-name pattern #文件的basename(不包括其前导目录的纯文件名)能被通配符模式的pattern匹配到。需要注意的是,在find中的通配元字符"*"、"?"和"[]"是能够匹配以点开头的文件的
-iname pattern #不区分大小的"-name"
-path pattern #文件名能被通配符模式的pattern匹配到。此模式下,通配元字符"*"、"?"和"[]"不认为字符"/"或"."是特殊字符,也就是说这两个字符也在通配范围内,所以能匹配这两个字符。
-ipath pattern #不区分大小写的"-path"
-regex pattern #文件名能被正则表达式pattern匹配到的文件。正则匹配会匹配整个路径,例如要匹配文件名为"./fubar3"
#的文件,可以使用".*bar."或".*b.*3",但不能是"f.*r3",默认find使用的正则类型是Emacs正则,但可以使用-regextype来改变正则类型
-iregex pattern #不区分大小写的"-regex"
文件权限判断
-perm mode #精确匹配给定权限的文件。"-perm g=w"将只匹配权限为0020的文件。当然,也可以写成三位数字的权限模式
-perm /mode #匹配任意给定权限位的权限,例如"-perm /640"可以匹配出600,040,700,740等等,只要文件权限的任意位能
#包含给定权限的任意一位就满足
-executable #具有可执行权限的文件。它会考虑acl等的特殊权限,只要是可执行就满足。它会忽略掉-perm的测试
-readable #具有可读权限的文件。它会考虑acl等的特殊权限,只要是可读就满足。它会忽略掉-perm的测试
-writable #具有可写权限的文件。它会考虑acl等的特殊权限,只要是可写就满足。它会忽略掉-perm的测试(不是writeable)
文件从属情况
-gid n #gid为n的文件
-group gname #组名为gname的文件
-uid n #文件的所有者的uid为n
-user uname #文件的所有者为uname,也可以指定uid
-nogroup #匹配那些所属组为数字格式的gid,且此gid没有对应组名的文件
-nouser #匹配那些所有者为数字格式的uid,且此uid没有对应用户名的文件
文件时间
-anewer file:atime比mtime更接近现在的文件。也就是说,文件修改过之后被访问过
-cnewer file:ctime比mtime更接近现在的文件
-newer file:比给定文件的mtime更接近现在的文件。
-newer[acm]t TIME:atime/ctime/mtime比时间戳TIME更新的文件
-amin n:文件的atime在范围n分钟内被访问过,对这个文件运用 more、cat等命令。ls、stat命令都不会修改文件的访问时间。注意,n可以是(+ -)n,例如-amin +3表示在3分钟以前
-cmin n:文件的ctime在范围n分钟内被修改过文件的状态,通过chmod、chown命令修改一次文件属性,这个时间就会更新
-mmin n:文件的mtime在范围n分钟内被修改过内容,vim/vi修改保存
-atime n:文件的atime在范围24*n小时内被访问过
-ctime n:文件的ctime在范围24*n小时内被修改状态
-mtime n:文件的mtime在范围24*n小时内被修改内容
-used n:最近一次ctime改变n天范围内,atime改变过的文件,即atime比ctime晚n天的文件,可以是(+ -)n
actions
actions部分一般都是执行某些命令,或实现某些功能。这部分是find的command line部分,注意,action是可以写在tests表达式前面的,它并不一定是在test表达式之后执行。
-delete #删除文件,如果删除成功则返回true,如果删除失败,将给出错误信息。"-delete"动作隐含"-depth"。
-exec command; #注意有个分号";"结尾,该action是用于执行给定的命令。如果命令的返回状态码为0则该action返回true。
#command后面的所有内容都被当作command的参数,直到分号";"为止,其中参数部分使用字符串"{}"时,它
#表示find找到的文件名,即在执行命令时,"{}"会被逐一替换为find到的文件名,"{}"可以出现在参数中的
#任何位置,只要出现,它都会被文件名替换。
#注意,分号";"需要转义,即"\;",如有需要,可以将"{}"用引号包围起来
-ok command ; #类似于-exec,但在执行命令前会交互式进行询问,如果不同意,则不执行命令并返回false,如果同意,则执
#行命令,但执行的命令是从/dev/null读取输入的
-print #总是返回true。这是默认的action,输出搜索到文件的全路径名,并尾随换行符"\n"。由于在使用"-print"时所有的结
#果都有换行符,如果直接将结果通过管道传递给管道右边的程序,应该要考虑到这一点:文件名中有空白字符(换行符、制表
#符、空格)将会被右边程序误分解,如文件"ab c.txt"将被认为是ab和c.txt两个文件,如不想被此分解影响,可考虑使
#用"-print0"替代"-print"将所有换行符替换为"\0"
-print0 #总是返回true。输出搜索到文件的全路径名,并尾随空字符"\0"。由于尾随的是空字符,所以管道传递给右边的程序,然后
#只需对这个空字符进行识别分隔就能保证文件名不会因为其中的空白字符被误分解
-prune #不进入目录,所以可用于忽略目录,但不会忽略普通文件。没有给定-depth时,总是返回true,如果给定-depth,则直接
#返回false,所以-delete(隐含了-depth)是不能和-prune一起使用的
-ls #总是返回true。将找到的文件以"ls -dils"的格式打印出来,其中文件的size部分以KB为单位
如果find评估完所有表达式后发现没有action(-prune这个action除外),则在最末尾加上-print作为默认的action。