zoukankan      html  css  js  c++  java
  • Linux命令之find(一)

    find命令的使用格式为:find options path expressions
    find命令事实上有两种options,一种是“真正属于自己的”,还有一种位于expressions内部。第一种选项一共就5个:-P -L -H -D -O。当中-D用来显示调试信息;-O用来指定优化级别,后面紧跟一个数字(没有空格),它们俩的详细信息能够看man。而-P -L -H的作用是“control the treatment of symbolic links”,不指定它们中的随意一个时,默觉得-P,即不跟踪链接。

    所谓跟踪链接是指:若被搜索的文件夹下有一个符号链接。且指向还有一个文件夹,那么被指向的文件夹也将被搜索。


    另外一种选项和第一种被path隔开,实际上,第一种选项比較少使用。find后面往往直接就是path。即要搜索的文件夹。假设不指定path,默觉得当前文件夹。搜索的时候,指定文件夹的子文件夹也是被搜索的对象。所以path能够视为start_dir。

    能够同一时候指定多个文件夹。


    真正的重头戏是expressions,它也有三部分:options test actions。

    因为path后面经常直接就是test,其它两项出现的也比較少,所以先从test開始。

    • -name pattern:匹配文件名称为“pattern”的全部文件。大多数情况下,我们都是依照文件名称来查找文件的,所以这是使用最频繁的选项。
      要注意:pattern中不应该包含路径名,仅仅有终于的文件名称。即basename是pattern。否则会报错,路径名应该在path中指定;这里要求文件名称和pattern必须全然一致。例如以下:

      m@meng:~$ ls tmp/
      onlyme  onlyme1  test.sh
      m@meng:~$ find tmp/ -name onlyme
      tmp/onlyme
      m@meng:~$ find tmp/ -name only
      m@meng:~$

      能够看到,仅仅写一部分名称是不会被匹配的。
      -name选项支持简单的shell字符扩展。如*、[]、?,当中*匹配随意数量的随意字符;?匹配一个随意字符。[]匹配随意一个出如今括号里的字符:

      m@meng:~/tmp$ find . -name onlym[eg]
      ./onlyme
      m@meng:~/tmp$ find . -name ?

      ?

      lyme ./onlyme m@meng:~/tmp$ find . -name on* ./onlyme

      更复杂的扩展就不支持了。这时就须要以下的-regex选项。


      -name还有几个变种:
      -iname:忽略大写和小写的-name;
      -lname:File is a symbolic link whose contents match shell pattern.这意思是匹配符号链接指向的文件名称,而不是符号链接名本身。


      -ilname:同上。忽略大写和小写。

    • -regex pattern:这里的pattern就能够是全然的正則表達式了,为防意外最好用引號括起来。

      pattern是用正則表達式表示的file name。


      -regex还有一个变种-iregex,能够忽略大写和小写。

    • -path pattern:因为-name选项不能使用路径分隔符(name中出现“/”会报错)。也就是无法选择子文件夹,可是某些情况下我们须要指定子文件夹或排除某些子文件夹(配合-prune)。所以就有了这个选项。
      要注意的是,-path后面的pattern必须曾经面指定的文件夹为起始路径:若指定文件夹是相对路径“.”,则pattern也必须以“.”开头;若指定文件夹是绝对路径,则pattern也要把这部分路径加在前面。例如以下:

      m@meng:~/patches$ ls tmp/
      new  nw  onlyme  test.sh
      m@meng:~/patches$ find . -path ./tmp/on*
      ./tmp/onlyme
      m@meng:~/patches$ find . -path tmp/on*
      m@meng:~/patches$ 
      m@meng:~/patches$ find /home/m/patches/ -path /home/m/patches/tmp/on*
      m@meng:~/patches$ /home/m/patches/tmp/onlyme

      -path也支持简单的元字符扩展。可是为了保险起见,最好把pattern用双引號括起来,例如以下:

      m@meng:~/patches$ find . -path ./tmp/*
      find: 路径必须在表达式之前: ./tmp/nw
      使用方法: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
      m@meng:~/patches$ find . -path "./tmp/*"
      ./tmp/nw
      ./tmp/onlyme
      ./tmp/test.sh
      ./tmp/new

      我看到非常多文章使用以下的方法来寻找子文件夹中的文件,本人实验后发现无论用:

      m@meng:~/patches$ find . -path ./tmp
      ./tmp
      m@meng:~/patches$ find . -path ./tmp -name onlyme
      m@meng:~/patches$ 

      我们看到,假设仅仅有子文件夹的名称(名称后面不要又斜线),那么就仅仅匹配子文件夹本身。而不会去把子文件夹以下的全部文件都匹配。而用path指定子文件夹后,再使用-name指定名称将不会得到想要的结果,所以仅仅能在pattern中把文件名称补上。然而以下这样的方法能够:

      m@meng:~/patches$ find . -path ./tmp -o -name onlyme
      ./tmp
      ./tmp/onlyme

      这里使用了-o选项。将在后面讨论。


    • -uid n以及-user name:都是依据文件的owner来匹配。前者依据owner的UID,后者依据name。

    • -gid n以及-group name:同上。仅仅是换成了group。
    • -nouser以及nogroup:若某个文件的属主或属组已经被删除。则匹配。


    • -type c:匹配文件类型为c的全部文件。c的详细值包含:f(普通文件)、b(块设备)、c(字符文件)、d(文件夹)、l(符号链接)等等。

    • -size:依据文件的大小来匹配。支持的单位包含c(bytes)、w(word,2bytes)、b(blocks,512bytes)、k(1024bytes)、M(1024k bytes)、G(1024M bytes)。

      m@meng:~/workspaces$ find . -size 1c 
      ./.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version      ./.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version
      ./.metadata/.plugins/org.eclipse.cdt.make.core/specs.c
      ./.metadata/.plugins/org.eclipse.cdt.make.core/specs.cpp
      m@meng:~/workspaces$ find . -size -1c 
      ./.metadata/.plugins/com.genuitec.org.hibernate.eclipse/hibernate-tools.log
      ./.metadata/.plugins/org.skyway.core/compass/index/core/clearcache
      m@meng:~/workspaces$ find . -size +2c -size -5c 
      ./.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache
      ./.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache

      test中经常要用到数字。所以必定会涉及数值范围问题。find给出的方法是,在数字前面加“+”表示大于该数字,而“-”表示小于该数字,没有符号表示等于该数字。

    • -inum n与-samefile name:依据是否是同一个文件来匹配。inum表示inode number,当一个文件的indoe与指定的n同样时,匹配;同理,-samefile直接使用文件名称,若某个文件与指定的name具有同样的inode,匹配。


    • -readable、-writable、-executable:非常显然,这是按文件权限来过滤文件的。

      比方,加上-executable,那么没有可运行权限的文件将会被过滤掉。


      只是,大家都知道,文件的权限分为三组。即用户(u)、群组(g)和其它(o),每组的权限又分为读(r)、写(w)和运行(x)。

      那么这三个选项究竟属于哪个组呢?我临时还没研究清楚,只是幸好find还有对权限进行匹配的更详细更经常使用的选项,就是以下的-perm。

    • -perm mode:依据文件的权限来匹配。可是指定权限mode的时候有三种模式:mode、-mode、/mode。
      纯mode格式意味着严格匹配,即每组权限都必须指定且全然一样,不能仅仅指定当中一组而其它组缺省。


      -mode格式就要宽松很多,比方-o=x,那么仅仅要一个文件的o组至少有x权限就能够匹配(有没有r和w权限无所谓)。而其它组无论;再比方-221,那意味着一个文件的u组和g组至少有w权限o组至少有x权限就能够匹配,于是-o=x相当于-001。所以-mode格式是“至少模式”。


      /mode格式还要宽松,在/mode格式指定的三组权限中,仅仅要有一组达到了“至少模式”。就能够成功匹配。

      能够用一个公式表达/mode。比方/124 <==> -100 || -020 || -004; /u=w,o=r <==> -u=w || -o=r。举几个样例吧:

      m@meng:~/tmp$ ls -lA
      总用量 8
      ---x-w---x 1 m    m     6  623 01:22 onlyme
      -rw-rw-r-- 1 root root  0  627 12:09 onlyme1
      -r-xr-x--x 1 m    m    66  623 02:57 test.sh
      m@meng:~/tmp$ find . -perm /242
      .
      ./onlyme1
      ./test.sh
      m@meng:~/tmp$ find . -perm /go=w
      .
      ./onlyme
      ./onlyme1
      m@meng:~/tmp$ find . -perm /go=x
      .
      ./onlyme
      ./test.sh
      m@meng:~/tmp$ find . -perm -g=x
      .
      ./test.sh
      m@meng:~/tmp$ find . -perm -120
      .
      ./onlyme
      m@meng:~/tmp$ find . -perm 121
      ./onlyme

    • -amin、-atime、-anewer:这三项都是依据文件的“上次訪问时间”属性来做匹配的。
      -atime n:文件的上次訪问时间是n天之前,则匹配。严格的说,n代表的事实上不是“天”,而是24小时,即从如今这一刻起,往前的24*n~24*(n+1)小时之内若文件被訪问过,则匹配,注意必须严格是这个区间。这里能够将n换成-n或+n。代表的范围各自是0~24*n和24*(n+1)~无穷大。
      -amin n:这里的n代表的是分钟。

      若文件的上次訪问时间与如今时间相差的分钟数是n-1。则匹配。


      -anewer file:计算出file的mtime,若某个文件的上次訪问时间在这个mtime之后,则匹配。


      相似的组合还有:-ctime、-cmin、-cnewer。这里仅仅是把上次訪问时间改成了上次更改时间;-mtime、-mmin、-newer,“上次訪问时间”改成上次修改时间。这三类时间的差别參见stat命令。

    • -newerXY file/time:这是上面那些选项的集大成者。。

      newer后面有两个占位符,它们的值能够是a、m、c、t分别代表上次訪问时间、上次modify时间、上次change时间和绝对时间;find依据Y的值来计算file的某个时间戳。然后依据X的值来做匹配。这里不举样例不行了:

      m@meng:~/tmp$ stat *
      File: ‘onlyme’
      Access: 2015-06-28 13:58:31.859458991 +0800
      Modify: 2015-06-28 12:49:16.115352584 +0800
      Change: 2015-06-28 13:58:31.859458991 +0800
      File: ‘test.sh’
      Access: 2015-06-28 13:39:07.203429170 +0800
      Modify: 2015-06-28 13:40:16.739430951 +0800
      Change: 2015-06-28 13:42:03.779433692 +0800
      m@meng:~/tmp$ find . -neweram onlyme 
      .
      ./onlyme
      ./test.sh
      m@meng:~/tmp$ find . -newerma onlyme 
      m@meng:~/tmp$
      m@meng:~/tmp$ find . -newermt "2015-06-28 13:23:16"
      .
      ./test.sh

      这里删去了一部分stat命令的输出。能够看到。同样是file=onlyme,当XY=am时。find计算出onlyme的mtime为2015-06-28 12:49:16。然后在指定文件夹中寻找那些atime在这个时间之后的文件,显然onlyme和test.sh的atime都符合条件;而XY=ma时,计算出onlyme的atime是2015-06-28 13:58:31。可是指定文件夹中任一文件的mtime都在这个时间之前。所以没有匹配。
      最后一个样例。令Y=t。然后指定一个绝对时间。接着搜索指定文件夹中mtime在这个时间之后的文件。

      显然。另X=t是无意义的,所以会报错。


    • empty:若一个文件是空的,而且不是普通文件或文件夹,则匹配。也能够说,若某个文件使用file命令的结果是empty。则匹配。
    • -links n:若某个文件的硬链接数量是n,则匹配。

    至此。test中经常使用的那些都介绍完了。能够看出find做文件匹配时主要基于以下几类文件属性:名称和路径;属主和属组;权限;大小、类型及inode;时间戳。其它。


    下篇介绍其它杂项。

  • 相关阅读:
    C#的内存管理原理解析+标准Dispose模式的实现
    深入理解C#:编程技巧总结(二)
    深入理解C#:编程技巧总结(一)
    深刻理解:C#中的委托、事件
    你知道JavaScript中的结果值是什么吗?
    switch语句的妙用
    相等比较、关系比较总结
    用ServiceStack操作使用redis的问题
    springmvc 处理put,delete请求
    easyui 验证动态添加和删除问题
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5172826.html
Copyright © 2011-2022 走看看