shell中find命令的使用要点
linux中的find的命令查找文件的重要方式,辅以其他的bash命令可以实现强大的操作效果。
先看看放find命令的基本组成:
find pathname -option [-print -exec -ok ...]
分类记忆各项属性参数~
pathname:指定find命令的查询根路径,例如 ‘ / ’,‘./ ' 等。
同时还可在-path参数中指定搜索路径。
-option:
1、文件操作:
-name 用引号” “将查询的文件名括起来,可适用于简单的正则表达式(应改为shell的元字符,下同)。
-type 指定查找文件的类型
b - 块设备文件。
d - 目录。
c - 字符设备文件。
p - 管道文件。
l - 符号链接文件。
f - 普通文件。
-size n 指定文件大小,若数字前+表示大于,-表示小于;常用单位c(字节),k(KB),M(MB)
2、用户权限:
-perm 用户权限permission,用常用的三位数字,如644表示权限。若数字前+表示至少包括指定的一种访问权限,-表示必须包括指定的所有访问权限
-user / -nouser 按文件属主查询 / 查找无有效属主的文件
-group / -nogroup 按文件所属租来查 / 查找无有效所属租的文件
3、时间选项:
-atime / -amin n 最近访问(accessed)过的文件,前者表示单位是天(24h),后者单位是分钟(minute);若数字前+表示n段时间前,-表示最近n段时间。后同。
-ctime / -cmin n 最近状态改变(changed)过的文件
-mtime / -mmin n 最近内容修改(modified)过的文件
-newer file!otherfile 查找更改时间比file新的文件,加上非(!)则查找比otherfile旧的文件
(注意,逻辑符号包括!(not)、-a(and)、-o(or),在命令中都是短路求值,简单讲就是若后面的参数不影响逻辑判断,则不对后面求值。在find命令中一般在选项之前添加逻辑符号)
4、文件路径:
-follow 遇到符号链接文件,就跟踪到链接指向的文件
-mount 不跨越文件系统的mount点,即在当前的文件系统查询,不进入其他文件系统(如挂载的windows系统)
-path 给出文件路径,可在路径中查询,满足简单正则表达式(元字符)。例如查找当前路径中' ./var/www '子目录中的’ index.html ’ 文件:
$ find . -path './var/www*' -name 'index.html' -print
./var/www/learn/study_smarty/templates/index.tpl
./var/www/learn/study_smarty/docs/index.php
./var/www/learn/index.php
./var/www/index.html
(结果中可以看到,-path选项中的参数要为模糊的查询条件,我理解的-path选项查找出的文件名实际上是带路径的字符串,而-path中则是满足结果字符串中的前面的路径字符。)
-prune 指出要忽略的目录。 结合-path选项,例如在当前目录下查找‘ index.html ’文件,同时忽略路径下的‘ /www/bin ’目录:
$ find . -path './www/bin' -prune -o -name 'index.html' -print
-path “./www/bin” -prune -o -name 'index.html' -print 是 -path “./www/bin” -a -prune -o -name 'index.html' -print 的简写表达式。按顺序求值,-a 和 -o 都是短路求值,与 shell 的 && 和 || 类似如果 -path “./www/bin” 为真,则求值 -prune , -prune 返回真,“与”逻辑表达式为真;否则不求值 -prune,与逻辑表达式为假。如果 -path “/usr/sam” -a -prune 为假,则求值 -name。-name返回真,“或”逻辑表达式为真;否则不求值 -name,“或”逻辑表达式为真。
(因此,其他的查询条件必须放在-o之后!而-path选项一般放在最前,-prune和-o也要连用)
避开多个文件可以用:
$ find /usr \(-path /usr/dir1 -o -path /usr/dir2 \) -prune -o -name "index.html" -print
‘ \(’ 与 ‘ \) ’ 表示转义,及shell不再对括号做特殊解释,这里转义后的括号表示结合。
(注意,路径后不能在加 ‘/’ 号!)
-depth 先匹配所有的文件,再在子目录中查找。即广度遍历查询。注意加上-depth选项后,-prune选项失效。
-maxdepth n 设定递归搜索的目录层级,1为在当前目录下,即不递归搜索。
5、查询执行:
-exec command {} \; 对查询的结果文件执行command 命令,{}中就包含着查询结果。
-ok command {} \; 与-exec有着相同的操作,不同的是,在执行command命令时会有交互提示你是否执行,是一种相对安全的做法。
在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高。转
xargs 与pipe连用,对匹配的文件执行操作。
find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。使用xargs命令则只有一个进程。转
例如,在当前路径下的普通文件中搜索‘ admin ’:
$ find . -type f -print | xargs grep 'admin'
对于一个参数的命令,xargs隐含传递匹配文件,如上述grep files,将结果隐含传递给files。如是多参数命令,如cp file dir,则要利用xargs的 -i 选项,例如将上述查询的问价copy至‘ /usr ’:
$ find . -type f -print | xargs -i cp {} /usr/
加上 -i 选项后,xargs将匹配的结果传递给 {} ,这样就方便多参数命令的使用了。
ok,打完手工,欢迎交流。