查找的艺术-find命令

如果你正气急败坏的在屏幕上双击打开一个又一个的文件夹疯狂寻找你两年前保存的关于“如何烹制独一无二的番茄炒蛋”的文章;如果你正盯着电脑上混乱如麻的文件夹,想把分散在各处的叫“菜谱XXX”的文件归并到一处,却无所适从时;如果你...

“嗨,这位使用Linux的大厨兄,别忙了,是时候学习一下Linux众多优秀文件管理工具中非常实用,趁手的一个了。find命令可以让您非常从容,优雅的按照您的吩咐来匹配相关的文件或目录(文件夹),并对其实施指定的操作。

find命令语法

find . -name foo -print

这个命令的意思是从当前目录开始搜索带有“foo“的文件并显示出来。

注:在多数的Linux版本中-print可以省略。

find的常用语法:

find    起始目录    搜寻条件

如果命令中没有设置起始目录,find会默认使用当前目录作为起始目录。你可以定义多个起始目录,比如:

find /usr /home /tmp -name "*.jar"

该命令会在/usr, /home, /tmp三个目录及其子目录下搜索带有“.jar“的文件。如果您对某些要搜索的起始目录及其子目录没有访问权限,在搜索过程中会生成错误消息,比如:
find: /root/protected: Permission denied
这样的出错信息会与搜索结果的输出混在一起。我们可以象如下这样过滤掉这些错误信息,以获得“干净”的搜索结果。
注:2>/dev/null 用来将出错信息重定向到空文件,从而不在屏幕上显示

find /usr /home /tmp -name "*.jar" 2>/dev/null

注:在上面的例子中通配符都需要括在引号中或用转义符(\)转义,比如上例也可以表示为:

find /usr /home /tmp -name \*.jar

find搜寻条件的逻辑及顺序

搜寻条件可以是多个条件组成的复合条件,可以由逻辑运算符and, or , not来连接:

  1. and: 逻辑与,在命令中用"-a"表示,是系统的缺省选项,表示只有当所给的条件都满足时,搜寻条件才满足。例如:
    find /prj/reports -type f -name '*.bak' \
    -exec grep -s DRAFT ‘{}’ \; -print

    注:第一行行末的\是续行符号表示下面一行的内容和本行是在一起的,一般用于把过长的一行内容分行输入。
    注:上述组合条件默认省略了-a“逻辑与”连接符,搜索条件之间以空格相连。
    上述命令表示搜索目标类型为文件(-type f),名称以".bak"结尾(-name ‘*.bak'),并且其中需包含DRAFT文字(-exec grep -s DRAFT '{}' \;)的文件,并显示出来(-print)。

    注:这里请注意复合条件的排列顺序,上例中如果将-name和-type放到-exec条件之后,那么find会对每一个遍历的文件及文件夹运行grep命令,这将浪费大量的时间。
    注:这里-exec以;结尾,{}表示符合之前搜索条件的文件,为防止与Shell的元字符冲突{};分别表示为'{}'\;

  2. or: 逻辑或,在命令中用"-o"表示。该运算符表示只要给出的条件中有一个满足时,搜索条件就算满足。例如:
    find -name '*.pyc‘ -o -name '*.pyo'

    表示搜索文件名包含.pyc或.pyo的所有文件。

  3. not: 逻辑非,在命令中用"!"表示。该运算符表示查找不满足给出条件的文件。例如:
    find !-name tmp

    搜索文件名不是tmp的所有文件

  4. 复杂组合条件:将以上3种逻辑运算组合运用,并使用()分组。例如:
    find /prj -type f \
      \(
       \( -name '*~' -mtime +7 -exec rm -f {} \; \) -o \
       \( -name core -atime +30 -exec rm -f {} \; \) -o \
       \( -name '*.bak' ! -perm 444 -exec chmod 444 '{}' \; \) \
      \)
  • 第一行命令表示让find搜索/prj目录及其子目录,-type f表示搜索的对象为文件。-type之后隐含了一个逻辑与。这个逻辑与的第二部分就是后面括在括号里的三行内容。
  • 括号中的三行之间是逻辑“或”的关系,这三个搜索表达式的任意一个为真,则上述逻辑与的第二部分为真。
  • 第二部分的第一句表示:搜索所有~结尾的,修改时间超过7天的所有文件,并其将删除;第二句表示搜索名为core,其访问时间超过30天的所有文件,并将其删除;第三句表示搜索以'.bak'结尾的,权限不是444的所有文件,并将它们的权限设置为444.

应用实例

  1. 搜索超过10000个字符的非压缩文件(没有.gz或bz2后缀),显示文件信息并询问是否用gzip压缩之:
    find archive -type f \
       ! -name '*.gz' ! -name '*.bz2' \
       -size +10000c -ls -ok gzip '{}' \;
  2. 复制当前目录下的子目录树(不拷贝文件,只创建空的子目录)
    cd /prj/daily/20081120
     
    find . -type d ! -name . \
    -exec mkdir /prj/daily/20081121/‘{}' \;

常用条件选项

  1. 以名称和文件属性查找。
    • - name ’字串’ 查找文件名匹配所给字串的所有文件,字串内可用通配符*、?、[ ]。
    • - lname ’字串’ 查找文件名匹配所给字串的所有符号链接文件,字串内可用通配符*、?、[ ]。
    • -gid n 查找属于ID号为n的用户组的所有文件。
    • -uid n 查找属于ID号为n的用户的所有文件。
    • -group ’字串’ 查找属于用户组名为所给字串的所有的文件。
    • -user ’字串’ 查找属于用户名为所给字串的所有的文件。
    • -empty 查找大小为0的目录或文件。
    • -path ’字串’ 查找路径名匹配所给字串的所有文件,字串内可用通配符*、?、[ ]。
    • -perm 权限 查找具有指定权限的文件和目录,权限的表示可以如711,644。
    • -size n[bckw] 查找指定文件大小的文件,n后面的字符表示单位,缺省为b,代表512字节的块。
    • -type x 查找类型为x的文件,x为下列字符之一:
      • b 块设备文件
      • c 字符设备文件
      • d 目录文件
      • p 命名管道(FIFO)
      • f 普通文件
      • l 符号链接文件(symbolic links)
      • s socket文件
      • -xtype 与-type基本相同,但只查找符号链接文件。
  2. 以时间为条件查找
    • - amin +n -n 按访问时间查找 -n指n分钟以内,+n指n分钟以前。
    • - atime +n -n 按访问时间查找 -n指n天以内,+n指n天以前。
    • - cmin +n -n 按创建时间查找 -n指n分钟以内,+n指n分钟以前。
    • - ctime +n -n 按创建时间查找 -n指n天以内,+n指n天以前。
    • - mmin +n -n 按修改时间查找 -n指n天以内,+n指n天以前。
    • - mtime +n -n 按修改时间查找 -n指n天以内,+n指n天以前。
  3. 可执行的操作
    • - exec 命令名称 {} 对符合条件的文件执行所给的Linux 命令,而不询问用户是否需要执行该命令。{}表示命令的参数即为所找到的文件;命令的末尾必须以“ ;”结束。
    • - ok 命令名称 { } 对符合条件的文件执行所给的Linux 命令,与exec不同的是,它会询问用户是否需要执行该命令。
    • - ls 详细列出所找到的所有文件。
    • - fprintf 文件名 将找到的文件名写入指定文件。
    • - print 在标准输出设备上显示查找出的文件名。

本文将持续更新欢迎提供板砖材料,当前版本:0.1_20081216

Leave a Response