Linux命令分析:find
来源:互联网 发布:软件更新 编辑:程序博客网 时间:2024/06/08 18:13
用途:在指定目录结构下查找特定文件
用法:find [-H] [-L] [-P] [-Olever] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
默认path为当前目录,默认expression为 -print
选项-H,-L和-P控制对符号链接的处理方式,必须位于path参数之前
find指令的执行原理是递归地遍历指定目录树,先执行五个real option选项(-P,-L,-H,-D,-Olevel)进行全局设置,然后对整个命令做语法检查,判断path及表达式的格式,表达式先根据operators进行结合,然后依次从左到右进行求值,对path中的每个文件依次执行表达式,由于要遍历目录甚至整个文件系统,故find命令执行较慢
参数:
-P 不跟踪符号链接(默认选项),只比对符号链接文件本身的属性
-L 跟踪符号链接,比对符号链接所指向的文件的属性(除非是broken symbolic link或find命令无法检查所指向的文件),该选项自带-noleaf参数,如果符号链接指向某个子目录,则find会搜索该子目录,-L选项与-lname和-ilname合用将报错
-H 不跟踪符号链接,除非是后面在命令行里指定文件是符号链接,在这种情况下,无论所链接的文件是什么都将以其属性比对,除非该符号链接是broken的,则以符号链接文件本身的属性比对,如果符号链接指向某个目录,则find会遍历该目录
注:如果-H,-L和-P中有多项被指定,则只有最后面的一项生效
-D 排错,在find无法找到期望的结果时有用,后接的参数用逗号隔开,这些参数在不同Linux发行版中不一定互通,以find -D help输出结果为准,以下为-D的参数:
help
tree 列出表达式目录树expression tree的初始形态和最终形态
stat 文件匹配过程中,当被stat或lstat系统调用检查时,将过程显示出来
opt 依据最优的表达式目录树显示diagnostic信息
rates 显示汇总信息,包括predicate判断式执行成功和失败的次数
-Olevel 开启查询优化,有0-3四个级别,对后面的查询参数进行排序,用于提高查询效率
表达式expression由选项options,判断式tests,动作actions组成,之间用逻辑运算符operators隔开,缺省operators是-and
当expression后面不接除了-prune,-print外的actions时,对所有返回值为true的文件有效
options针对的是本次查找操作而不是某个 文件,通常返回值为true,除了-daystart,-follow和-regextype这三个选项,因为options通常在find程序对命令行进行语法检查之前就已经执行了,而上述三个选项和后面命令行输入的判断式有关,故为清晰起见,规定这三个选项要写在expression开头,否则会warning
-d 等效于-depth,同时与FreeBSD,NetBSD,MacOS X和OpenBSD兼容
-daystart 从本日0点开始计算时间(包括-amin -atime -cmin -ctime -mmin -mtime)
-depth 先遍历目录下的内容,然后才检查目录文件本身
-follow 不跟踪符号链接,-L会使之失效,隐含-noleaf选项
-ignore_readdir_race find命令在目录里读到某文件存在,在检查该文件信息之前如果该文件被删除,本选项将不会报错
-maxdepth levels 设置遍历目录的最大层级,即最多只遍历到目录下第levels层
-mindepth levels 设置遍历目录的最小层级,即只遍历第levels层下面的目录,当前目录的子目录深度为1,子目录的子目录深度为2,-mindepth1意味着处理目录下所有文件
-mount 仅在当前文件系统执行,与-xdev等效,且可兼容其他版本的find
-noleaf 不为“目录中子目录数量为硬链接数-2”这种假设做搜索优化,这个选项在搜索不遵循UNIX文件系统链接约定的那些文件系统时有用,find查找文件实际上是stat每个目录文件的内容,对目录来说,只遍历到比其硬链接数少2个子目录后就不再向下检查了,这是因为对于一个典型的类UNIX系统来说,一个目录文件至少有两个硬链接,分别是/和./,另外如果其下还有子目录,则子目录还有个上级目录文件../,那就至少是三个硬链接了,所以find默认假设目录拥有其硬链接数-2个子目录,硬链接数为2的目录为directory tree的leaf,程序到此不再向下stat,极大的提高了搜索速度
-regextype type 如果不指定该选项,默认正则表达式语法是emacs,该选项可指定语法,目前支持posix-awk,posix-basic,posix-egrep和posix-extended
-xautofs 不在autofs挂载的文件系统执行
-xdev 不在当前文件系统外执行
tests判断式可将后面命令行里指定的文件与path中的文件进行比对,其中可含三种数字参数:
+n 比n大
-n 比n小
n 等于n
-amin n 文件在之前第n分钟时被access过(即atime在now-3min和now-2min之间),具体算法是(当前时间-atime)/ 1min,然后再取整数部分加1
-anewer file 文件的atime比文件的mtime要晚,前面有-L或-H选项时,比对symbolic link将使用被链接文件的atime
-atime n 对文件的最后访问是n天之前,算法是(当前时间-atime)/ 24hours,然后取整。故-atime +1代表文件2天前被访问过
-cmin n 对文件的mtime改变发生在之前第n分钟
-cnewer file 文件的ctime比mtime要晚,前面有-L或-H选项时,比对symbolic link将使用被链接文件的ctime
-ctime n 文件的ctime是在n天前,算法同-atime
-executable 用于匹配文件是否可执行或目录是否可搜索,与-perm判断的机制不同,只是调用access(2)这个system call,因此有可能被开启了UID mapping功能的服务器所误导,最后得到的文件不一定都可实际执行
-false 总是返回false值
-fstype type 文件在type类型的文件系统上,有效的文件系统类型在不同版本的UNIX上是不同的,一些版本上的不完全列表有:ufs,4.2,4.3,nfs,tmp,mfs,S51K,S52K,可用-printf %F指令来查找你的文件系统类型
-gid n 文件的数字形式的组ID为n(n为/etc/group里组所对应的数字)
-group gname 文件属于gname组(gname变量可用数字组id)
-ilname pattern 与-lname类似,但不区分大小写
-lname pattern 文件是符号链接,使用后接的pattern字符串来匹配,若该字符串中含有metacharacter(元字符,BASH中的特殊字符,由shell解释)"."或"/",只当其是普通字符,不作特殊解释,与-L或-follow合用时无效
-iname pattern 与-name类似,但不区分大小写
-inum n 文件的inode号为n,通常用来查看硬链接,可用-samefile代替
-iregex pattern 与-regex类似,但不区分大小写
-iwholename pattern 与-wholename类似,但不区分大小写
-links n 文件有n个硬链接
-mmin n 对文件的mtime改变发生在之前第n分钟
-mtime n 文件的mtime是在n天前,算法同-atime
-name pattern 用文件名(路径去除了前面的目录,比如/etc/passwd的文件名是passwd)去匹配后接的pattern字符串,元字符* ? [ ]可以通配文件名开头的".",使用-prune来略过某个目录及其下文件。该参数调用fnmatch(3)这个库函数来匹配文件,注意要给pattern字符串加上引号来确保shell不会对其中的特殊字符进行解释
-newer file 查找比参考file的mtime时间更晚的文件,与-L或-L参数合用时,file若是符号链接则采用其链接到文件的mtine
-newerXY reference 将文件的时间戳与变量reference进行比对,reference可以是文件名也可以是个表示时间的字符串,X和Y是两个占位符,可以从下列参数中选择填充,这些参数指定了用来比对的时间类型
a 使用atime比对
B 使用文件的创建时间比对
c 使用ctime比对
m 使用mtime比对
t reference本身就是时间
以上的填充参数有些不可滥用,比如X位不可用t,参数B不是所有的发行版都支持
-nogroup 查无有效所属组的文件,即文件的属组在/etc/groups中不存在
-nouser 查无有效属主的文件,即文件的属主在/etc/passwd中不存在
-path pattern 文件名与shell模式的pattern匹配,元字符"/","."不做特殊处理。例如,find . -path "./sr*sc"会找到./src/misc这个文件(如果存在的话)。如果要忽略一个完整的目录树,应使用-prune这样就不用检查目录树中的每个文件了,例如要跳过/src/emacs这个目录及其下所有文件,可以这样:find . -path ./src/emacs -prune -o print
注意,pattern变量用来匹配的是采用完整文件名的test,即在path指明的路径下遍历文件,匹配这些文件的绝对路径(目录名+文件名),比如下面这个命令就无法生效:find bar -path /foo/bar/myfile -print 因为bar不是有效的目录名,无法与-path后面的pattern组成完整文件名
-perm mode 文件的权限位等于mode变量(八进制数或符号),该命令要求文件权限严格等于mode,比如-perm g=w就只会匹配到权限为0020的文件(-----w----),通常我们更愿意用/mode或-mode参数,因为他们可以匹配到所有所属组有w权限的文件
-perm -mode 文件的权限位包含mode变量(比如文件权限为0777,mode为0711),mode可用符号,但必须形如u= g= o= 这样指定对特定对象的权限,例如-perm -u=7
-perm /mode 文件的权限位转换成八进制数里任一位中的1与mode中对应,比如某文件权限为644,转换城八进制数为110 100 100,这时候find . -perm /001是找不到该文件的,而find . -perm /400就能找到该文件。如果-perm /后面不接mode,等效于-perm -000(匹配到所有文件)
-readable 匹配可读属性的文件,同-executable一样,该参数也是通过access(2)系统调用执行
-regex pattern 匹配pattern这个正则表达式的文件,这里匹配的是whole path全称路径,即要搜索./fubar3这个文件,应该用'.*bar'或'.*b.*3'这样的表达式,而不能用'f.*r3'这样的,因为无法匹配到前面的./目录名。默认使用emacs正则表达式语法,也可通过-regextype指定其他语法
-samefile name 与name变量指定文件inode号相同的文件,-L启用时,可匹配符号链接
-size n[cwbkMG] 文件占用n个存储单元,默认单位是512B的block,可在n后面加后缀指定存储单元大小,可选后缀如下:
b 大小为512字节的block(默认)
c 1字节的单元
w 2字节的单元
k 1KB的单元(1024B)
M 1MB的单元(1048576B)
G 1GB的单元(1073741824B)
注:size中不计入间接块indirect block(inode所在block记录不完文件的blocks,在末尾加一个指针,指向另一个block继续记录),同时也不计入稀疏文件中未实际分配的block
-true 总是返回true
-type c 文件是c类型的,类型可选值如下:
b 特殊块文件(缓冲的) #如/dev/sda /dev/loop0等,find / -type b自行查看
c 特殊字符文件(不缓冲) #如/dev/null等
d 目录文件
p 命名管道FIFO
f 普通文件
l 符号链接
s 套接字socket
D 门(Solaris特有)
-uid n 文件的数字形式的用户ID为n(n为/etc/passwd里组所对应的数字)
-used n 文件的最后一次access是在最后一次状态被修改(ctime)的n天以后
-user uname 文件的所有者是uname(可使用userID)
-writable 匹配可写属性的文件,同-executable一样,该参数也是通过access(2)系统调用执行
-xtype c 和-type相同,除非文件是个符号链接。对于一个符号链接,在-H或-P选项指定的情况下,如果指向的是一个变量c类型的文件,则返回true;在-L选项指定的情况下,如果变量c是“l”即符号链接,则返回true。换句话说,-xtype检查的是-type忽略的符号链接所指向文件
-context pattern 匹配安全上下文security context为parttern的文件
actions是针对某个具体文件进行的操作,如下:
-delete 删除匹配到的文件,删除成功后返回true,如果删除失败,会显示error message。该参数自带-depth选项,由于find命令行是按照表达式来解释的,如果把-delete放在expression开头有可能使find试图删除path起点下的所有文件,所以一定要确切指出遍历的深度。-delete和-prune参数不可合用
-exec command 执行-exec后面接的命令,返回值为0则为true。find命令的强大功能很大程度上来自于这个操作,可将前面find找到的文件调用外部命令进行处理。-exec后接的所有参数都将被视为command,直到出现;为止,所以这个命令后面一定要接分号,同时应该在;前加上转义符\以防止其被shell解释为特殊字符。-exec后接的命令会对find到的每个文件执行一次,所以用字符串{}代替当前正在处理的文件名,command中出现的所有{}都会被替换(有的版本find则不然,只替换某个单独参数下的{}),}与\;之间一定要有一个空格,所以该命令的一般形式是find . EXPR1 -exec command {} \; 命令是从起始目录开始执行的。-exec操作会带来一些不可避免的安全问题,可以用-execdir代替
-exec command {} + 类似-execdir command {} + 只是从起始目录开始执行
-execdir command {} + 与-exec command相比,主要解决两个问题:一是find命令在-exec下会将所有匹配到的文件一起传递给command执行,但有的系统对能传递给exec的命令长度有限制,这样find运行一段时间后会溢出,exec后面加+的作用是使每次find建立的command line只包含同一个子目录里的匹配文件,这时要确保PATH环境变量中不包含"."字符。另外一个对每一个匹配的文件,-exec后接的命令都会建立一个线程,一方面线程过多可能引发系统性能下降,另一方面线程共享内存和某些寄存器,因此不同线程在解析所匹配到的文件的path时,可能引发race conditions竞争条件,而-execdir每次只同时匹配同一子目录里的文件,其path相同,能避免race conditions。
其实更好的办法是使用xargs,xargs可以自行设定每次获得多少参数来执行,find命令配合xargs和exec几乎可以对匹配到的文件执行所有命令
-fls file 返回值为true;类似-ls但是像-fprint那样写入file
-fprint file 返回值为true;将文件全名打印到文件file中。如果find运行时file不存在,则会创建一个,如果存在,则会被覆盖。文件名/dev/stdout和/dev/stderr会作特殊处理,他们分别指的是标准输出和标准错误输出
-fprint0 file 返回值为true;类似-printf0但像-fprint那些写入file
-fprint file format 返回值为true;类似-printf但像fprint那样写入file
-ls 返回值为true;以ls -dils这样的格式列出当前文件并打印到标准输出。默认的block是1K大小,除非在环境变量POSIXLY_CORRECT中设置
-ok command 类似-exec但执行命令前先向用户询问(在标准输入),显然这样更安全
-okdir command 类似-execdir但执行命令前先询问用户
-print 返回值为true;在标准输出打印文件全名,然后接一个换行符。该参数主要用于将find的输出通过管道传递给其他程序时,某些文件名有可能含有换行符
-print0 返回值为true;打印文件全名到标准输出,后接一个null字符。这样可以使处理find的输出的程序可以正确解释带有换行符的文件名,该参数等效于xargs -0
-printf format 返回值为true;在标准输出打印format,会解释\ 转义和% 变量。字段宽度和精度可像C函数printf那样来指定。不同于-print,-printf不会在字符串后加换行符,可用的escapes和directives如下:
\a 警告铃声
\b 退格 Backspace
\c 立即停止以当前格式输出并刷新输出设备
\f 换页 Form feed
\n 换行 Newline
\r 回车 Carriage return
\t 水平制表符
\v 竖直制表符
\0 ASCII字符NUL
\\ 输出一个\
\NNN ASCII编码是八进制NNN的字符
\作为转义符,后接的任何字符都会被当作普通字符打印输出
%% 只输出一个%
%a 文件最后一次access时间,采用C函数ctime返回值的格式
%Ak 文件最后一次access时间,采用变量k指定的格式,可以是"@"或C函数strftime的指令格式,下面列出了k可用的值,部分不是所有系统可用,因为不同系统中strftime也不同
@ 从Jan.1,1970,00:00 GMT起的秒数,带小数部分
时间字段
H 小时(00到23)
I 小时(01到12)
k 小时(0到23)
l 小时(1到12)
M 分钟(00到59)
p locale中的AM或PM
r 12小时格式的时间 hh:mm:ss [AP]M
S 秒(00到61),带小数部分
T 24小时格式的时间 hh:mm:ss
* 日期和时间,中间用+隔开,形如 2004-04-28+22:22:05.0 秒所在字段带小数部分
X locale中的时间表示法 H:M:S
Z 时区(如EDT),不指定时为空
日期字段
a locale中的一星期中每天名称的缩写(Sun至Sat)
A locale中的一星期中每天名称的全拼,可变长度(Sunday至Saturday)
b locale中的每月名称的缩写(Jan到Dec)
B locale中的每月名称的全拼,可变长度(January到December)
c locale中时间和日期表示,形如 Sat Nov 04 12:02:33 EST 1989 该格式与ctime(3)函数相同,为保证两者的兼容性,此处秒字段无小数部分
d 每月当中的日子(01到31)
D 日期(mm/dd/yy)
h 与b相同
j 一年当中的日子(001到366)
m 月份(01到12)
U 以周日为每周起始,一年中的星期(00到53)
w 每星期中的日子(0到6)
W 以周一为每周起始,一年中的星期(00到53)
x locle中的日期表示(mm/dd/yy)
y 年份的最后两位(00到99)
%b 文件大小,以512B大小的block数为单位Y 年份(从1970开始)
%c 文件状态的最后一次修改时间,采用C函数ctime返回值的格式
%Ck 文件状态的最后一次修改时间,格式由变量k指定,类似%Ak
%d 文件在目录树中的深度,0代表文件是命令行参数
%D 文件所在的设备号(结构体的st_dev字段),十进制数
%f 去掉了前面目录的文件名
%F 文件所在的文件系统类型,该值可为-fstype所用
%g 文件的组名,或组ID号
%G 文件的组ID号
%h 文件名前面的目录部分
%i 文件的inode号
%k 文件大小,以1K block数为单位
%l 符号链接的目标(如果文件不是符号链接则为空字符串)
%m 文件的权限位(八进制)。
%M 文件的权限位(符号形式,形如ls列出的)
%n 文件的硬链接数
%p 文件名
%P 文件名,去掉了文件名中使之得以被找到的命令行参数
%s 文件大小,以字节为单位
%S 文件稀疏度 计算公式是 BLOCKSIZE*st_blocks / st_size
%t 文件内容的上一次修改时间,采用C函数mtime返回值的格式
%Tk 文件内容的最后一次修改时间,格式由变量k指定,类似%Ak
%u 文件的用户名,或用户ID
%U 文件的用户ID
%y 文件类型,形如ls -l所列出的,U代表未知类型
%Y 文件类型,类似%y,增加了以下symlinks:L为loop,N为nonexistent
%Z 文件的安全上下文(SELinux only)
在printf中%用来表示格式化输出,其本身将被省略,接在其后的所有字符都将被视为普通字符打印输出
-prune 位于要排除的目录后,没有给出-depth时返回值为true;不进入前面指定的目录,如果给出了-depth则返回false,由于-delete隐含了-depth,故不可与-prune合用
-quit 立即退出,未执行命令的文件将不再执行
operators 逻辑运算符,下面将按优先级从高到低排列:
(expr) 用括号将表达式括起来具有最高的优先级,由于shell中括号有特殊含义,一般会加转义符,形如 \(...\) 而不是 (...)
! expr 表达式的值为false则返回true
-not expr 与! expr相同,但不遵循POSIX规范
expr1 expr2 两个表达式之间隐含默认运算符and,若expr1为false则不执行expr2
expr1 -a expr2 同上
expr1 -and expr2 同上,但不遵循POSIX规范
expr1 -o expr2 逻辑运算符或,若expr1为真则expr2不会执行
expr1 -or expr2 同上,但不遵循POSIX规范
expr1,expr2 列表,expr1和expr2都会被执行,expr1的值被忽略,最后列出的是expr2的值
典型用法:
在/根目录下查找文件名以ifcfg开头的文件,比如网卡配置文件
在/var/log下查找.log后缀的文件,字符.代表当前目录
3.查找文件全名中包含某些字符的文件
如上,查找到与BASH变量有关的文件,双引号可以解释内含字符串中的变量符号$
4.查找特定路径下特定文件名的特定类型文件
-type判断式可查找特定类型文件,后接-ls操作对传递来的文件名列出详细信息,本例为和passwd有关的链接文件
5.查找文件时使用通配符
上面字符串表示查找文件名中第一个字符为数字,第二个字符为大写字母的文件;第二条命令中的?代表文件名中一定有第三个字符
6.在特定目录深度匹配文件
查找/etc下第一层有几个config目录
7.查找特定时间戳的文件
查找24小时内被修改过内容的普通文件(mtime),比如上面的日志文件
注:有的版本算法可能得到的是(n-1)*24 hours 至 n*24 hours 这段时间内被修改的文件,我的版本实测是得到小于n*24 hours内被修改的文件
有时候要的时间比较精确,不想计算是多少天或分钟前的时候,可以自行创建一个参考文件,指定其时间戳,然后通过-newer来判断
8.查找特定权限的文件
上为查找/var/log下权限为750的文件
查找/var/lib目录下other用户至少有执行权限的文件,-perm -mode可匹配大于或等于其的权限
9.查找特定大小的文件
上为找一个大于100M的文件,如果要找小于100M的则为-size -100M
10.查找属于特定用户或组的文件
查找指定用户root的邮件
11.搜索时忽略个别目录
通常格式是find PATH -path 要忽略的目录 -prune test action
12.将搜索结果打印到标准输出
查找根目录下ntp用户所有的文件并打印出权限
13.调用外部命令
将/var/log下的.log文件复制到/tmp目录,上面命令中-exex后全部视为command,对前面的每个文件执行一次,{}代表当前正在执行的文件,\;代表command结束
统计/usr/bin下脚本文件的个数,使用管道和xargs命令配合更灵活,find找到的文件作为参数一个个传递给xargs执行
14.使用逻辑连接符进行复杂查找(! -a -o)
如上,括号内的表达式具有最高优先级,同时括号前要加转义符,上为找到/目录下除/var和/tmp目录里的所有.log文件
- Linux命令分析:find
- linux命令:find命令
- linux命令:find命令
- linux下find命令详解与实例分析
- Linux命令:du+find分析目录大小,清理空间
- linux unix Find 命令
- linux find命令
- Linux Find命令
- linux find 命令实例
- Linux--find命令2
- Linux之find命令
- Linux find命令详解
- Linux命令-Find
- Linux命令之find
- linux find 命令实例
- linux find命令
- linux find 命令实例
- Linux find命令详解
- (CSU
- Servlet程序及Servlet的应用
- mybatis的selectKey功用
- E/ExoPlayerImplInternal: Source error.
- 《TCP IP网络编程》尹圣雨----8.第五章源码展示
- Linux命令分析:find
- bzoj2618 [Cqoi2006]凸多边形(半平面+S)
- Count and say[easy on LeetCode]
- kmalloc、vmalloc、malloc的区别
- Median of Two Sorted Arrays(获取两个有序数列的中值)
- 实现射线检测鼠标拖动物体移动和使用滑轮缩放物体
- Android给Activity状态栏设置自定义颜色
- 华为机试-数字颠倒
- 前端感官性能的衡量和优化实践