Linux命令之find(二)

本文发布时间: 2019-Mar-22
上篇文章已经介绍了expressions的的test,它是find命令最核心的东西,现在介绍expressions的options和actions。(一)options-d,-depth:二者作用相同,man手册和很多博客上都说它们的作用是:首先查找当前目录文件,然后再在其子目录查找。不过我自己实验了很多次,发现没什么效果。。。烦请高人指点~-maxdepth:指定最大目录深度,也就是指定目录的几级子目录:1代表只是指定目录本身;2表示一级子目录;3代表“孙目录”,以此类推。。。 m@meng:~/patches/tmp$ find . -maxdepth 1 -name 'onlyme*' ./onlyme ./onlyme1 m@meng:~/patches/tmp$ find . -maxdepth 2 -name 'onlyme*' find . -maxdepth 2 -name 'onlyme*' ./test/onlyme5 ./test/onlyme.sh ./onlyme ./onlyme1-mindepth:类似上面的-maxdepth,但是指定的是最小深度。比如指定 2,那就是只搜索深度大于2的各级子目录,而不理会小于2的那些目录(小于2的就是指定目录本身),如下例: m@meng:~/patches/tmp$ find . -mindepth 1 -name 'onlyme*' ./test/onlyme5 ./test/onlyme.sh ./onlyme ./onlyme1 m@meng:~/patches/tmp$ find . -mindepth 2 -name 'onlyme*' ./test/onlyme5 ./test/onlyme.sh-help:显示帮助信息,并退出。 -mount或-xdev:如果某个(子)目录是另一个文件系统的挂载点,则跳过该目录。 -daystart:先看man手册的说法:Measure times (for -amin, -atime, -cmin, -ctime, -mmin, and -mtime) from the beginning of today rather than from24 hours ago. 看来这个选项只影响那些跟时间有关的test,而且改变了时间的计算方式,即不再从当前时刻开始计算,而是从每天的0:00开始计算。前面说过,-atime n,这个n并不代表实际的“一天”,而是指24小时;但是加上-daystart这个选项之后,就可以真的代表“一天”了,因为这时就是从每天的0:00开始计时的,看下面的例子:m@meng:~/patches/tmp$ date2015年 07月 12日 星期日 00:13:47 CSTm@meng:~/patches/tmp$ stat new最近访问:2015-07-12 00:10:15.707908310 +0800最近更改:2015-07-12 00:10:15.707908310 +0800最近改动:2015-07-12 00:10:15.707908310 +0800m@meng:~/patches/tmp$ stat test最近访问:2015-07-11 23:42:25.064527595 +0800最近更改:2015-07-06 23:57:45.095385673 +0800最近改动:2015-07-06 23:57:45.095385673 +0800m@meng:~/patches/tmp$ find -atime 0../test./newm@meng:~/patches/tmp$ find -daystart -atime 0../new这就很显然了,在没有加上-daystart这个选项之前,-atime 0指的是从当前这一刻开始,往前的24小时之内,如果某个文件被访问过,则匹配;但是加上-daystart之后,-atime 0表示今天被访问过的文件才会匹配。同理-atime 1表示昨天(即7/11 0:00 ~ 7/11 23:59)被访问过的文件才会匹配。这个选项的作用可以简单归纳为:化零为整。(二)actions-delete:找到匹配的文件之后,将其删除。man手册上提到:Use of -delete automatically turns on the -depth option,不过我还没搞懂这个-depth到底有什么卵用。。 -print:这个是默认的action,即没有指定任何action的时候其实就是使用了这个-print,但是指定了另一个action的时候,就必须显式加上-print才有效果。它把每个匹配的文件打印到标准输出上,每行一个文件。这意味着,-print在打印的时候,每个文件末尾添加了一个换行符。但是这个换行符是为了浏览方便,有时会造成一些麻烦,比如使用管道的时候;如果想省略这个换行符,可以用-print0来代替,如下: m@meng:~/patches/tmp$ find -daystart -atime 0 -print . ./new m@meng:~/patches/tmp$ find -daystart -atime 0 -print0 ../newm@meng:~/patches/tmp$所以,如果只是想在终端观察输出,没有必要使用-print0,-print就足够了。-print还有一个变种是-printf,类似于C语言中的printf函数,进行格式化输出,暂时不研究了,有太多格式。-ls:类似于ls命令的-dils选项组合,如下: m@meng:~/patches/tmp$ find -daystart -atime 0 -ls 7478778 4 drwxrwxr-x 3 m m 4096 7月 12 00:10 . 7478967 0 -rw-rw-r-- 1 m m 0 7月 12 00:10 ./new m@meng:~/patches/tmp$ ls -dils new 7478967 0 -rw-rw-r-- 1 m m 0 7月 12 00:10 new换了一种更详细的输出而已。f系列,即-(fls/fprint/fprint0/fprintf) file,这几个action与没有开头f的那几个action是非常相似的,只是不再把结果打印到标准输出,而是输出到文件file中。-exec command ;与-exec command {} +-exec本身其实只是在find执行完之后执行另一条命令,我之前以为-exec类似于管道,find找到的文件会直接被command处理,结果不是这样;若想要达到管道的效果,需要在 command后面添加“{}”,它代表前面找到的文件。然后是语法问题:command后面没有“{}”时,必须要以一格空格和一个分号结尾;command后面有“{}”时,可以使用前面那种结尾方式,也可以使用一个空格和一个“+”结尾;为了防止shell本身的扩展,分号需要转义,要么前面添加反斜线,要么用引号括起来;同理“{}”最好也用引号保护起来。 m@meng:~/patches/tmp$ find . -name new -print -exec cat onlyme1 ; ./new haha m@meng:~/patches/tmp$ find . -name new -print -exec cat onlyme1 + find: 缺少“-exec”参数 m@meng:~/patches/tmp$ find . -name new -print -exec cat {} ; ./new hello m@meng:~/patches/tmp$ find . -name new -print -exec cat {} + ./new hello m@meng:~/patches/tmp$ find . -name new -print -exec cat {} ';' ./new hello m@meng:~/patches/tmp$ find . -name new -print -exec cat {} ';' ./new hello第一个例子说明command和find之间可以是完全独立的;第二个说明command后面没有“{}”时只能以分号结尾;后面几个例子说明了有“{}”时的结尾情况。-execdir command ;和-execdir command {} +与上一对选项类似,只是-exec后面的command是在当前目录执行的;而-execdir是在匹配文件所在子目录中执行的。我们使用pwd命令测试一下: m@meng:~/patches/tmp$ lsmagic.mgc new onlyme onlyme1 testm@meng:~/patches/tmp$ ls test/onlyme5 onlyme.shm@meng:~/patches/tmp$ find . -name onlyme.sh -exec pwd ;/home/m/patches/tmpm@meng:~/patches/tmp$ find . -name onlyme.sh -execdir pwd ;/home/m/patches/tmp/test文件onlyme.sh在子目录test中,find在找到它之后执行pwd命令;但是-exec和-execdir的结果是不同的。-ok与-okdir与-exec和-execdir是基本相同的,只是在执行之前会先询问一下用户。 -pruneif the file is a directory, do not descend into it. 就是说,如果某个目录匹配了,那么就不再进入这个目录进行搜索。 m@meng:~/patches/tmp$ find . -name 'test*' ./test./test/test1m@meng:~/patches/tmp$ find . -name 'test*' -prune ./test我们看到,匹配 -name ‘test*’的包括test子目录本身以及test目录下的test1文件;但是加上-prune选项之后,就不在进入到test目录中进行搜索了,因为test目录本身也是一个匹配项。-prune经常配合-path用来排除某些子目录。-quit立即退出,-quit之后的命令将不再执行。如下: m@meng:~/patches/tmp$ find . -name new -print -exec cat {} ';'./newhellom@meng:~/patches/tmp$ find . -name new -print -quit -exec cat {} ';'./newm@meng:~/patches/tmp$ find . -name new -print -exec cat {} ';' -quit./newhellom@meng:~/patches/tmp$ find . -name new -quit -print -exec cat {} ';' m@meng:~/patches/tmp$(三)逻辑运算先扔一段man手册的信息:The expression is made up of options (which affect overall operation rather than the processing of a specific file, and always return true),tests(which return a true or false value), and actions (which have side effects and return a true or false value), all separated by operators.-and is assumed where the operator is omitted.If the expression contains no actions other than -prune, -print is performed on all files for which the expression is true.这就是说,expression的三个组成部分其实都是布尔表达式,而表达式都是有值的,不是true就是false。手册说,options的值永远是true;而其他两者的值可true可false。这样,就会有逻辑运算,其实主要是test之间的运算,因为一个expression里面可以有多个test,这些test之间可以进行与、或、非运算。比如上篇文章中的例子:m@meng:~/patches$ find . -path ./tmp -o -name onlyme./tmp./tmp/onlyme至此,find命令的基本用法完毕~好累。上面的总结肯定有不完善的地方,我会再以后慢慢补充慢慢纠正的。


(以上内容不代表本站观点。)
---------------------------------
本网站以及域名有仲裁协议。
本網站以及域名有仲裁協議。

2024-Mar-04 02:09pm
栏目列表