操作系统中的文件上前上万,对于linux这样“一切皆文件”的操作系统来说更不例外,所以当我们需要查找一个特定格式的文件时,难免需要一些特殊工具帮我们快速找到,linux下查找文件的命令有两个:

locate,find

    接下来将详细描述下这两个命令的具体用法。首先说locate,

  1. locate: locate命令其实是“find -name”的另一种写法,但是要比后者快得多,原因在于它不搜索具体目录,而是对其生成的数据库进行遍历(/var/lib/locatedb),这个数据库中含有本地所有文件信息,这一特性决定了用locate查找文件速度很快,但是locate命令只能对文件进行模糊匹配;但是Linux系统自动创建的这个数据库,并且每天自动更新一次,所以使用locate命令查不到最新变动过的文件。为了避免这种情况,可以在使用locate之前,先使用updatedb命令,手动更新数据库。

  2. 那么其特性如下:

    1. 依赖于实现构建好的索引库;

    2. 系统自动实现;(周期性任务);

    3. 手动更新数据库(updatedb);

    4. updatedb需要遍历整个根文件系统,非常消耗系统资源;

    5. 模糊查找;

    6. 查找速度快;

    7. 非实时查找;

  3. 具体用法:locate [OPTIION] …PATTERN

  • -b: 只匹配路径中的基名

  • -c: 统计出共有多少个符合条件的文件

  • -r :基于正则表达式编写

  • -i :忽略大小写

  • 实例:$ locate /etc/sh   #搜索etc目录下所有以sh开头的文件

  • 实例:$ locate ~/m      #搜索用户主目录下,所有以m开头的文件

  • 实例:$ locate -i ~/m   #搜索用户主目录下,所有以m开头的文件,并且忽略大小写

  • 实例:$ locate -ci ~/m  搜索用户主目录下,所有以m开头的文件,并且忽略掉大小写之后这样的文件的个数


然后讲find,是一种实时查找工具,通过遍历制定起始路径下文件系统层级结构完成文件查找。

其特性如下:

  1. 查找速度略慢;

  2. 精确查找;

  3. 实时查找;

用法如下:

find [OPTION] [查找起始路径][查找条件][处理动作],解释如下:


  1. 查找起始路径:指定具体搜索目标起始路径,默认为当前目录;

  2. 查找条件:指定的查找标准,可以根据文件名,大小,类;型,从属关系,权限等等,如果不指条件,默认为找出指定路径下所有文件

  3. 处理动作:对符合查找条件的恩建做出的判断,例如删除等操作;默认为输出至标准输出;

在这其中,查找条件及处理动作又是重中之中。



就查找条件来说,分为:

  1. 根据文件名查找

  2. 根据文件从属关系查找

  3. 根据文件类型查找

  4. 根据文件大小查找

  5. 根据时间戳查找

  6. 根据权限查找


分别就这些条件意义解析:

  1. 根据文件名:顾名思义,就以文件的名字作为查找条件。

  • -name pattern 

  • -iname pattern 忽略大小写

  • 支持glob风格通配符,比如 * ?[] [^]

  • -regux patern 基于正则表达式查找文件,匹配整个路径

根据文件从属关系进行查找。
  • -user USERNAME:查找属主指定用户的所有文件

  • -group GRPNAME:查找属组指定用户的所有文件

  • -uid  UID : 查找属主指定UID的所有文件

  • -gid GID :查找属组指定GID的所有文件

  • -nouser:     查找没有属主的文件

  • -nogroup:查找没有属组的文件

根据文件的类型查找:
  • -type TYPE

    • f:普通文件

    • d:目录

    • l:符号连接文件

    • b:块设备文件

    • c:字符设备文件

    • p:管道文件

    • s:套接字文件

根据文件的大小查找。
  • -size[+][-]# UNIT

    • 常用单位:k M G 

根据时间戳查找。
  • 以”天“为单位:

    • -atime  [+][-] #   访问时间

    • -mtime  [+][-] #   内容修改时间

    • -ctime  [+][-] #   属性修改时间

根据权限查找
  • -perm [/|+] mode

    • /mode: 任何一类用户(u,g,o)的权限中的任何一位(r,w,x)符合即可,或关系;

    • -mode :每一类用户(u,g,o)权限中的每一位(r,w,x)同时候符合条件,与关系。


实例:

  1. 找出/tmp目录下属主为非root的所有文件:

  • find /tmp -not -user  root -ls

找出/tmp目录下文件名不包含fstab字符串的文件:
  • find /tmp -not -iname  "*fstab*"   -ls

找出/tmp目录下属主为非root,而且文件名不包含fstab字符串的文件
  • find /tmp/ -not -user root  -a -not -iname "*fstab*" -ls

  • find /tmp/ -not \(-user root -o -iname "*fatab*"\) -ls

  • 其中-a表示and -o表示满足其一即可,-not表示非, 所以第二种写法为组合写法

  • !A -a !B = !(A -o B)  !A -o !B=!(A -a B)

查找/var目录下属主为root,且属组为mail的所有文件或目录;
  • find /var/ -user root -a -group mail -ls

查找/usr/目录下不属于root,bin或Hadoop的所有目录或文件;用两种方法
  • find /usr -not -user root  -a -not -user bin -a -not -user hadoop

  • find /usr -not \(-user root -o -user bin -o -user hodoop\) -ls

查找/etc/目录下最近一周内其内容修改过,且属主不是root用户也不是Hadoop用户的文件或目录;
  • find /etc/ -mtime -7 -a -not \(-user root -o -user Hadoop \) -ls

查找当前系统上没有属或属组,且最近一周内曾被访问过的文件或目录;
  • finmd / \( -nouser -a -nogroup \) -atime -7 -ls

查找/etc目录下大于1M且类型为普通文件的所有文件;
  • find /etc -size +1M -type f -exec ls {} \;

找/etc目录下所有用户都没有写权限的文件;
  • find /etc -perm -not /mode 222 -type f -ls

查找/etc目录至少有一类用户没有执行权限的文件;
  • find /etc -perm -not mode -111 -type f -ls

查找/etc/init.d/目录下,所有用户都有执行权限,且其它用户有写权限的所有文件;
  • find /etc/init.d -perm -111 -a -perm -002 -ls

  • find /etc/init.d -perm -113 -ls

  • 将两者权限合并




最后在说说处理动作,有如下解释:

  • -print : 输出至标准输出

  • -ls:     类似于对查找到文件执行”ls -l“命令,输出文件的详细信息;

  • -delete: 删除查找到的文件

  • -fls /PATH/TO/SOMEFILE: 把查找的所有文件的详细信息保存至指定文件中

  • -ok COMMAND {} \;  对查找到的文件执行由COMMAND表示的命令,每次操作由用户确认

  • -exec COMMAND {} \; 对查找到的文件执行由COMMAND表示的命令,每次操作不询问用户


最后我们还可以用xargs命令使用管道作为find传递的参数进一步进行,比如:

find /opt -name "*.old" |xargs chmod 700 进一步对查找到的文件赋权。

xargs的命令选项如下:

  1. -a file 从文件中读入作为sdtin

  2. -e flag ,注意有的时候可能会是-E,flag必须是一个以空格分隔的标志,当xargs分析到含有flag这个标志的时候就停止

  3. -p 当每次执行一个argument的时候询问一次用户

  4. -n # 后面加次数,表示命令在执行的时候一次用的argument的个数,默认是用所有的

  5. -t 表示先打印命令,然后再执行

  6. -i 将xargs的每项名称,一般是一行一行赋值给{},可以用{}代替

  7. -r no-run-if-empty 当xargs的输入为空的时候则停止xargs,不用再去执行了

  8. -s num 命令行的最好字符数,指的是xargs后面那个命令的最大命令行字符数


到这里,基本就把find的基本用法解释完毕。