【Linux】一步一步学Linux——find高级用法(48)

00. 目录

01. 命令概述

find命令可以根据给定的路径和表达式查找的文件或目录。find参数选项很多,并且支持正则,功能强大。和管道结合使用可以实现复杂的功能,是系统管理者和普通用户必须掌握的命令。

find如不加任何参数,表示查找当前路径下的所有文件和目录,如果服务器负载比较高尽量不要在高峰期使用find命令,find命令模糊搜索还是比较消耗系统资源的。

exec解释

-exec 参数后面跟的是command命令,它的终止是以;为结束标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面加反斜杠。

{} 花括号代表前面find查找出来的文件名。

使用find时,只要把想要的操作写在一个文件里,就可以用exec来配合find查找,很方便的。在有些操作系统中只允许-exec选项执行诸如l s或ls -l这样的命令。大多数用户使用这一选项是为了查找旧文件并删除它们。建议在真正执行rm命令删除文件之前,最好先用ls命令看一下,确认它们是所要删除的文件。 exec选项后面跟随着所要执行的命令或脚本,然后是**{ },一个空格和一个\,最后是一个分号**。为了使用exec选项,必须要同时使用print选项。如果验证一下find命令,会发现该命令只输出从当前路径起的相对路径及文件名。

xargs解释

在使用 find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。

find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。

在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高; 而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。

02. 命令格式

find [path…] [expression]

03. 常用选项

NAME
       find - 递归地在层次目录中处理文件
描述
       这个文档是GNU版本find命令的使用手册。find搜索目录树上的每一个文件名,它从左至右运算给定的表达式,按照优先规则(见运算符OPERATORS一节)进行匹配,直到得出结果(左边运算在'与'操作中得出假,在'或' 操作中得出真),然后find移向下一个文件名。
       第一个以'-','(',')',',''!'这些字符起始的参数是表达式的开始;
       在它之前的任何参数是要搜索的路径,在它之后的任何参数都是表达式的余下部分。
       如果没有路径参数,缺省用当前目录。如果没有表达式,缺省表达式用'-print'.

       当所有文件都成功处理时find退出并返回状态值0。如果发生错误则返回一个大于0的值。

表达式
        表达式是由选项(选项总是影响所有的操作,而不仅仅是一个指定的文件的处理,而且总是返回真值),测试(测试返回一个真值或一个假值),还有动作(动作有side effects,返回一个真值或假值)组成。它们都以运算符分开.忽 略运算符的时候,默认使用-and连接.如果表达式没有包含-prune以外的动作,当表达式为真时会执行-print 动作。
   选项 OPTIONS
       所有的选项都总是返回真值,它们总会被执行,除非放在表达式中执行不到的地方。
       因此,清楚起见,最好把它们放在表达式的开头部分。

       -daystart
              从当日起始时开始而不是从24小时之前,计算时间(for    -amin,
              -atime, -cmin, -ctime, -mmin, and -mtime)。
       -depth 先处理目录的内容再处理目录本身。
       -follow
              不检索符号链接。隐含了 -noleaf。
       -help, --help
              列出 find 的命令行用法的概要,然后退出。
       -maxdepth levels
              进入命令行参数指定的目录下层目录时,最深不超过lev‐els(一个非负整数)层。`maxdepth0'意味着只在命令行参数指定的目录中执行测试和动作。
       -mindepth levels
              不在levels(一个非负整数)层之内执行任何测试和动作。`-min‐depth 1'意
              味着处理所有的文件,除了命令行参数指定的目录中的文件。
       -mount 不进入处于其它文件系统之上的目录。可以用-xdev代替,从而和一些其他版本的
              find 兼容。
       -noleaf
              不为“目录中子目录数量比硬连接数少2”这种假设做优化。这个选项在搜索那些不遵
              循UNIX文件系统链接约定的文件系统时用,比如CD-ROM,MS-DOS文件系统或AFS卷的
              加载点。在普通的UNIX文件系统中,每个目录至少有两个硬连接,它的名字和它
              的   '.'  条目。另外,它的子目录(假如有)还会各有一个  '..'链接到它。在find
              检索一个目录时,发现子目录数比它的连接数少二时,它就知道目录中的其他条目
              并非目录(而是目录树中的叶(`leaf')节点)。除非需要检索的是这个叶节点,否则
              没必要去处理它。这样可以带来很大的搜索速度提升。
       -version, --version
              打印find的版本号然后退出。
       -xdev  不进入处于其他文件系统之上的目录。

   测试 TESTS
       数字参数可以这样给出:
       +n     是比 n 大,
       -n     是比 n 小,
       n      正好是 n 。
       -amin n
              对文件的最近一次访问是在 n 分钟之前
       -anewer file
              对文件的最近一次访问比   file   修改时间要晚。如果命令行中
              -follow 在 -anewer 之前,(也只有在这种情况下) -anewer 会受
              -follow 的影响。
       -atime n
              对文件的最近一次访问是在 n*24 小时之前。
       -cmin n
              对文件状态的最近一次修改是在 n 分钟之前。
       -cnewer file
              对文件状态的最近一次修改比 file 修改时间要晚。如果命令行中
              -follow 在 -cnewer 之前,(也只有在这种情况下) -cnewer 会受
              -follow 的影响。
       -ctime n
              对文件状态的最近一次修改是在 n*24 小时之前。
       -empty 文件是空的普通文件或者空目录。
       -false 总是false。
       -fstype type
              文件处于type
              类型的文件系统之上。有效的文件系统类型在不同版本的Unix中是不同的;一些Unix中的不完全的文件系统类型列表是这样:ufs,4.2, 4.3, nfs, tmp, mfs, S51K, S52K. 你可以用 -printf 加上
%F 指令来查看你的文件系统的类型。
       -gid n 文件的数字形式的组ID是 n。
       -group gname
              文件属于 gname (也允许使用数字形式的组ID).
       -ilname pattern
              和 -lname 类似,但是匹配时是不区分大小写的。
       -iname pattern
              和 -name 类似,但是匹配时是不区分大小写的。例如,`fo*' and
              `F??' 模式与文件名 `Foo', `FOO', `foo', `fOo' 等等相匹配。
       -inum n
              文件的 i 结点数是 n。
       -ipath pattern
              和 -path 类似,但是匹配时是不区分大小写的。
       -iregex pattern
              和 -regex 类似, 但是匹配时是不区分大小写的。
       -links n
              文件有 n 个链接。
       -lname pattern
              文件是一个与pattern 匹配的符号链接。元字符不会对`/'`.'
              做特殊处理。
       -mmin n
              对文件数据的最近一次修改是在 n 分钟之前。
       -mtime n
              对文件数据的最近一次修改是在 n*24 小时之前。
       -name pattern
              基本的文件名(将路径去掉了前面的目录)与shell模式pat‐
              tern相匹配。元字符(`*',        `?',       还有`[]'       )
              不会匹配文件名开头的`.'           。使用            -prune
              来略过一<standard input>:349: warning [p 7, 2.7i]: can't break line
<standard input>:360: warning [p 7, 4.5i]: cannot adjust line
个目录及其中的文件。查看 -path 的描述中的范例。

       -newer file
              对文件的最近一次修改比   file   修改时间要晚。如果命令行中
              -follow 在 -newer 之前,(也只有在这种情况下)  -newer  会受
              -follow 的影响。
       -nouser
              没有符合文件的数字形式的用户ID的用户。
       -nogroup
              没有符合文件的数字形式的组ID的组。
       -path pattern
              文件名与shell模式pattern相匹配。元字符不会对`/'   或   `.'
              做特殊处理。因此,例如:find . -path './sr*sc'如果存在'./src/misc'
              的话,会将它打印出来。想要忽略一个完整的目录树,应当使用-prune
              而不是检查目录树中所有的文件。例如:要跳过     'src/emacs'
              目录和其中所有的文件和子目录,把其他找到的文件打印出来,应当这样:find . -path './src/emacs' -prune -o -print

       -perm mode
              文件的权限位恰好是 mode  (八进制或符号)。  Symbolic  modes
              use mode 0 as a point of departure.
       -perm -mode
              所有的权限位 mode 都被设置了的文件。
       -perm +mode
              任何权限位 mode 被设置了的文件。
       -regex pattern
              文件名与正则表达式pattern匹配。这是对整个路径的匹配,不是搜索文件。例如,要匹配名为`./fubar3'的文件,可以使用正则表达式`.*bar.'或者`.*b.*3',但是不能用`b.*r3'。

       -size n[bckw]
              文件使用了n单位个存储单元。默认的单位是512字节的块,也可以用n后面加上
              `b' 来指定这个值。其他的单位是字节,如果在 n 后面加上  `c'
              ;千字节(kB),如果在  n 后面加上`k' ;两字节的字,如果在 n
              后面加上`w'。大小不会计入indirectblocks,但是会计入没有真正分配空间的疏松文件中的块。
       -true  总是true。
       -type c
              文件是 c 类型的。类型可取值如下:
              b      特殊块文件(缓冲的)
              c      特殊字符文件(不缓冲)
              d      目录
              p      命名管道 (FIFO)
              f      普通文件
              l      符号链接
              s      套接字
              D      门 (Solaris 特有)

       -uid n 文件的数字形式的用户ID是 n 。
       -used n
              文件最后一次存取是在最后一次修改它的状态的 n 天之后。
       -user uname
              文件的所有者是 uname (也可以使用数字形式的用户ID).
       -xtype c
              和-type相同,除非文件是一个符号链接。对于符号链接:如果没有给出
              -follow,如果文件是一个指向c类型文件的链接,那么返回true;如果给出了 -follow ,如果c是`l'那么返回true。换句话说,对于符号链接,-xtype检查那些 -type 不检查的文件。

   动作
       -exec command ;
              执行command;如果命令返回状态值0,那么exec返回true。所有find
              其余的命令行参数将作为提供给命令的参数,直到遇到一个由 `;'
              组成的参数为止。命令的参数中,字符串`{}'
              将以正在处理的文件名替换。所有的`{}'
              都会被替换,不仅是在单独的一个参数中。有些版本的find
              不是这样做的。这些参数可能需要用`\'来escape
              或者用括号括住,防止它们被shell展开。命令是从起始目录执行的。

       -fls file
              返回true;类似 -ls 但是像 -fprint 那样写入 file。
       -fprint file
              返回true;将文件全名打印到文件 file 中。如果运行  find  时
              file不存在,那么它将被创建。如果它存在,它将被覆盖。文件名``/dev/std‐
              out''``/dev/stderr''会作特殊处理;它们分别指的是标准输出和标准错误输出。

       -fprint0 file
              返回true;类似 -print0 但是像 -fprint 那样写入 file。

       -fprintf file format
              返回true;类似 -printf 但是像 -fprint 那样写入 file。

       -ok command ;
              类似 -exec 但是会先向用户询问 (在标准输入); 如果回应不是以
              `y'`Y' 起始则不会运行 command 而是返回false。

       -print 返回true;在标准输出打印文件全名,然后是一个换行符。

       -print0
              返回true;在标准输出打印文件全名,然后是一个null字符。这样可以使得处理
              find 的输出的程序可以正确地理解带有换行符的文件名。

       -printf format
              返回true;在标准输出打印 format , 解释 `\' escape 还有 `%'
              指令。字段宽度和精度可以像C函数   `printf'  那样来指定。与
              -print                  不同的是,                  -printf
              在字符串末端不会添加一个新行。可用的escape 和指令如下:
              \a     警告铃声
              \b     回退
              \c     立即停止以当前格式输出,刷新输出设备。
              \f     表格结束
              \n     新行
              \r     回车
              \t     水平tab
              \v     竖直tab
              \\     输出自身`\'
              \NNN   ASCII编码是NNN(八进制)的字符

              在一个`\'字符后面使用任何其他字符会被作为普通的字符,因此它们都会被打印出来。

              %%     输出自身`%'
              %a     文件最后一次存取的时间。格式是C函数         `ctime'
                     返回值的格式。
              %Ak    文件最后一次存取的时间。格式以 k  指定,可以是  `@'
                     或者是C函数   `strftime'  的指令格式。下面列出了  k
                     可用的值;有一些并不是在所有系统上都可用,因为不同系统中
                     `strftime' 也不同。
                     @      从 Jan. 1, 1970, 00:00 GMT 起的秒数
                     时间字段:
                     H      小时 (00..23)
                     I      小时 (01..12)
                     k      小时 ( 0..23)
                     l      小时 ( 1..12)
                     M      分钟 (00..59)
                     p      本地的 AM 或者 PM
                     r      12小时格式的时间 (hh:mm:ss [AP]M)
                     S      秒 (00..61)
                     T      24小时格式的时间 (hh:mm:ss)
                     X      本地的时间表示方法 (H:M:S)
                     Z      时区(例如,EDT),如果不能决定时区就是空
                     日期字段:
                     a      本地一星期中每天的名称的缩写(Sun..Sat)
                     A      本地一星期中每天的全名,可变长度       (Sun‐
                            day..Saturday)
                     b      本地每月的名称的缩写 (Jan..Dec)
                     B      本地每月的全名,可变长度 (January..December)
                     c      本地的日期和时间表示 (Sat  Nov  04  12:02:33
                            EST 1989)
                     d      一个月当中的日子 (01..31)
                     D      日期 (mm/dd/yy)
                     h      与 b 相同
                     j      一年当中的日子 (001..366)
                     m      月份 (01..12)
                     U      以星期日作为每周起始,一年当中的星期
                            (00..53)
                     w      一星期当中的日子 (0..6)
                     W      以星期一当作每周起始,一年当中的星期
                            (00..53)
                     x      本地的日期表示 (mm/dd/yy)
                     y      年份的最后两位 (00..99)
                     Y      年份 (1970...)

              %b     文件大小,以512字节的块为单位 (四舍五入)。
              %c     文件状态最后一次修改的时间。格式是C函数     `ctime'
                     返回值的格式。
              %Ck    文件状态最后一次修改的时间。格式以k指定,类似于%A。
              %d     文件在目录树中的深度;0
                     意味着文件是一个命令行参数。
              %f     去掉了前面的目录的文件名 (只剩下最后的成分)。
              %F     文件所在文件系统的类型;这个值可以为 -fstype 所用。
              %g     文件的组名,如果组没有名称就是数字形式的组ID。
              %G     文件的数字形式的组ID。
              %h     文件名的前面的目录部分 (仅除去最后的成分)。
              %H     据以找到了文件的命令行参数。
              %i     文件的 i 结点号(16进制)。
              %k     文件大小,以1kB 的块为单位 (四舍五入)。
              %l     符号链接的目标
                     (如果文件不是一个符号链接,那么结果是空字符串)。
              %m     文件的权限位 (8进制)。
              %n     文件的硬连接数。
              %p     文件名。
              %P     文件名,去掉了据以找到了文件的命令行参数的名称部分。
              %s     文件大小,以字节为单位。
              %t     文件最后一次修改的时间。格式是C函数         `ctime'
                     返回值的格式。

              %Tk    文件最后一次修改的时间。格式以 k 指定,类似于%A。
              %u     文件的用户名,如果用户没有名称就是数字形式的用户ID。
              %U     文件的数字形式的用户ID。
              在一个    `%'    字符后面使用任何其他字符,`%'    将被忽略
              (但是其他字符会被打印出来)。

       -prune 如果没有给出 -depth 则返回 true; 不进入当前目录。
              如果给出了 -depth 则返回false; 没有效果。

       -ls    返回true;以  `ls  -dils'  格式在标准输出列出文件。块以1kB
              字节为单位计数,除非设置了环境变量POSIXLY_COR‐
              RECT,那样的话会使用 512字节的块。

   运算符
       以优先级高低顺序排列:
       ( expr )
              强制为优先
       ! expr 如果 expr 是false则返回true
       -not expr! expr 相同
       expr1 expr2
              与 (隐含的默认运算符);如果 expr1 为false则不会执行 expr2
       expr1 -a expr2
              与 expr1 expr2 相同
       expr1 -and expr2
              与 expr1 expr2 相同
       expr1 -o expr2
              或;如果 expr1 为true 则不会执行 expr2
       expr1 -or expr2
              与 expr1 -o expr2 相同
       expr1 , expr2
              列表;expr1和expr2都会被执行。expr1的值被忽略,列表的值是 expr2的值

04. 参考示例

4.1 查找匹配的文件之后,使用ls命令显示详细信息

[deng@localhost share]$ find ./ -name "a.out" -exec ls -l {} \;
-rwxrwxr-x 1 deng deng 8800 7月  11 15:16 ./6th/a.out
-rwxrwxr-x 1 deng deng 13872 7月  13 14:41 ./7th/2HMAC/a.out
-rwxrwxr-x 1 deng deng 8440 7月  13 16:31 ./7th/tmp/a.out
[deng@localhost share]$ 

4.2 在指定目录中查找更改时间在n日以前的文件并删除它们

[deng@localhost share]$ find ./ -type f -mtime +7 -exec rm {} \;

4.3 在目录中查找更改时间在n日以前的文件并删除它们,在删除之前先给出提示

[deng@localhost share]$ find ./ -name "a.out" -mtime +2 -ok rm {} \;   
< rm ... ./6th/a.out > ? n
< rm ... ./7th/2HMAC/a.out > ? n
< rm ... ./7th/tmp/a.out > ? n
[deng@localhost share]$ 

说明:find命令在当前目录中查找所有文件名以a.out结尾、更改时间在2日以上的文件,并删除它们,只不过在删除之前先给出提示。 按y键删除文件,按n键不删除。

4.4 在指定的目录中查找文件,然后通过搜索出现root的行

[root@localhost /]# find /etc -name "passwd*" -exec grep "root" {} \;
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost /]# 

说明:任何形式的命令都可以在-exec选项中使用。 在上面的例子中我们使用grep命令。find命令首先匹配所有文件名为“ passwd*”的文件,例如passwd、passwd.old、passwd.bak,然后执行grep命令看看在这些文件中是否存在一个root用户。

4.5 查找文件移动到指定的目录

[deng@localhost share]$ find ./ -name "a.out" -exec mv {} . \;
[deng@localhost share]$ ls
5th  6th  7th  8th  9th  a.out
[deng@localhost share]$ 

4.6 exec中执行cp命令

[deng@localhost share]$ find ./ -name "test.cpp" -exec cp {} ./ \;
[deng@localhost share]$ ls
5th  6th  7th  8th  9th  test.cpp
[deng@localhost share]$ 

4.7 查找当前目录下所有的test.cpp,然后使用xargs命令来测试它们分别属于哪类文件

[deng@localhost share]$ find ./ -name "test.cpp" | xargs file
./5th/1client/test.cpp:        C source, UTF-8 Unicode text
./5th/2server/test.cpp:        C source, UTF-8 Unicode text
./6th/10ShmClassRead/test.cpp: C source, UTF-8 Unicode text
./6th/9ShmClassWrite/test.cpp: C source, UTF-8 Unicode text
./7th/1ShmClass/test.cpp:      C source, UTF-8 Unicode text
./7th/2HMAC/test.cpp:          C source, UTF-8 Unicode text

4.8 在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件

[root@localhost ~]# find / -name "core" -print | xargs echo > /tmp/core.log

4.9 在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的执行权限

[deng@localhost share]$ find ./ -perm -7 -print | xargs chmod o-x
[deng@localhost share]$ ls -l a.out
-rwxrwxrw- 1 deng deng 0 7月  16 19:19 a.out
[deng@localhost share]$ 

4.10 用grep命令在所有的普通文件中搜索root

[root@localhost ~]# find /etc -name "passwd" | xargs grep "root"
/etc/passwd:root:x:0:0:root:/root:/bin/bash
/etc/passwd:operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]# 

4.11 用grep命令在指定目录下的所有普通文件中搜索root这个词

[root@localhost ~]# find ./ -name \* -type f -print | xargs grep "root"

注意,在上面的例子中, \用来取消find命令中的*在shell中的特殊含义。

4.12 xargs执行mv命令

[deng@localhost share]$ find ./ -name "a.out" | xargs -i mv {}  ./ 
[deng@localhost share]$ ls
5th  6th  7th  8th  9th  a.out  test.cpp
[deng@localhost share]$ 

4.13 find后执行xargs提示xargs: argument line too long解决方法

[deng@localhost share]$   find . -type f -atime +0 -print0 | xargs -0 -l1 -t rm -f

-l1是一次处理一个;-t是处理之前打印出命令

4.14 使用-i参数默认的前面输出用{}代替,-I参数可以指定其他代替字符,如例子中的[]

[deng@localhost test]$ find ./ -name "a.out" | xargs -I [] cp [] ./
[deng@localhost test]$ ls
a.out  share
[deng@localhost test]$ 

说明:使用-i参数默认的前面输出用{}代替,-I参数可以指定其他代替字符,如例子中的[]

4.15 xargs 中-p表示需要用户确认

[deng@localhost test]$ find ./ -name "a.out"  | xargs -p -i mv {} ./
mv ./share/a.out ./ ?...y
[deng@localhost test]$ ls
a.out  share
[deng@localhost test]$ 

说明:-p参数会提示让你确认是否执行后面的命令,y执行,n不执行。

4.16 查找当前目录或者子目录下所有.txt文件,但是跳过子目录test

[deng@localhost test]$ find . -path "./test" -prune -o -name "*.txt" -print

4.17 查找当前目录下所有长度为0的文件

[deng@localhost test]$ find ./ -empty
./share/5th/1client/client.cpp
./share/6th/txt
./share/7th/3SecKeyClient/bin/x64/Debug
./share/8th/1SecKeyClient/bin/x64/Debug
./share/8th/2SecKeyServer/bin/x64/Debug
./share/8th/a.txt
./share/9th/SecKeyServer/bin/x64/Debug
./a.out
[deng@localhost test]$ 

4.18 根目录$HOME中查找文件名符合*.log的文件,

使用~作为 'pathname’参数,波浪号~代表了你的$HOME目录。

[deng@localhost test]$ find ~ -name "*.log" 
/home/deng/.cache/gdm/session.log
/home/deng/.local/share/gvfs-metadata/root-6f39759a.log
/home/deng/.local/share/gvfs-metadata/home-daa2468f.log
/home/deng/oradiag_deng/diag/clients/user_deng/host_61728193_80/trace/sqlnet.log
[deng@localhost test]$ 

4.19 在当前目录及子目录中查找所有的‘ *.log‘文件

[deng@localhost test]$ find . -name "*.log" -print 
[deng@localhost test]$ 

4.20 当前目录及子目录中查找文件名以一个大写字母开头的文件

[deng@localhost test]$ find ./ -name "[A-Z]*" 

4.21 在/etc目录中查找文件名以host开头的文件

[deng@localhost test]$ find /etc -name "host*" 

4.22 查找$HOME目录中的文件

[deng@localhost test]$ find ~ -name "*"   
[deng@localhost test]$ find . 

4.23 在当前目录查找文件名以一个个小写字母开头,最后是4到9加上.log结束的文件

[deng@localhost test]$ find ./ -name "[a-z]*[4-9].log" 
[deng@localhost test]$ 

4.24 根据权限查找另外一种方法

[deng@localhost test]$ find ./ -perm -005

在八进制数字前面要加一个横杠-,表示都匹配,如-007就相当于777,-005相当于555

4.25 查找过程中忽略某个目录

希望在test目录下查找文件,但不希望在test/test1目录下查找
[deng@localhost test]$ find / -path "test/test1" -prune -o -print

如果在查找文件时希望忽略某个目录,因为你知道那个目录中没有你所要查找的文件,那么可以使用-prune选项来指出需要忽略的目录。在使用-prune选项时要当心,因为如果你同时使用了-depth选项,那么-prune选项就会被find命令忽略。

在路径列表的后面的是表达式

-path “test” -prune -o -print 是 -path “test” -a -prune -o -print 的简写表达式按顺序求值, -a 和 -o 都是短路求值,与 shell 的 && 和 || 类似如果

-path “test” 为真,则求值 -prune , -prune 返回真,与逻辑表达式为真;否则不求值 -prune,与逻辑表达式为假。如果 -path “test” -a -prune 为假,则求值 -print ,-print返回真,或逻辑表达式为真;否则不求值 -print,或逻辑表达式为真。

这个表达式组合特例可以用伪码写为:

if -path "test" then  

-prune  

else  

-print  

4.26 避开多个文件

[root@localhost soft]# find test \( -path test/test4 -o -path test/test3 \) -prune -o -print

说明:圆括号表示表达式的结合。 \ 表示引用,即指示 shell 不对后面的字符作特殊解释,而留给 find 命令去解释其意义。

4.27 其它

find . -name   "[A-Z]*"   -print   #查以大写字母开头的文件
find . -name   "[a-z][a-z][0–9][0–9].txt" -print  #查以两个小写字母和两个数字开头txt文件
find -name april*        在当前目录下查找以april开始的文件
find -name   april*   fprint file  在当前目录下查找以april开始的文件,并把结果输出到file中
find -name ap* -o -name may*   查找以ap或may开头的文件
find /mnt  -name tom.txt  -ftype vfat   在/mnt下查找名称为tom.txt且文件系统类型为vfat的文件
find /mnt -name t.txt ! -ftype vfat   在/mnt下查找名称为tom.txt且文件系统类型不为vfat的文件
find /tmp   -name wa* -type l            在/tmp下查找名为wa开头且类型为符号链接的文件
find /home   -mtime   -2                 在/home下查最近两天内改动过的文件
find /home    -atime -1                  查1天之内被存取过的文件
find /home -mmin    +60                  在/home下查60分钟前改动过的文件
find /home   -amin   +30                  查最近30分钟前被存取过的文件
find /home   -newer   tmp.txt             在/home下查更新时间比tmp.txt近的文件或目录
find /home   -anewer   tmp.txt            在/home下查存取时间比tmp.txt近的文件或目录
find /home  -used  -2             列出文件或目录被改动过之后,在2日内被存取过的文件或目录
find   /home   -user cnscn                列出/home目录内属于用户cnscn的文件或目录
find   /home   -uid   +501                  列出/home目录内用户的识别码大于501的文件或目录
find   /home   -group   cnscn              列出/home内组为cnscn的文件或目录
find   /home   -gid 501                   列出/home内组id为501的文件或目录
find   /home   -nouser                    列出/home内不属于本地用户的文件或目录
find   /home   -nogroup                   列出/home内不属于本地组的文件或目录
find   /home    -name tmp.txt    -maxdepth   4   列出/home内的tmp.txt 查时深度最多为3层
find   /home   -name tmp.txt   -mindepth   3   从第2层开始查
find   /home   -empty                     查找大小为0的文件或空目录
find   /home   -size   +512k                查大于512k的文件
find   /home   -size   -512k               查小于512k的文件
find   /home   -links   +2                查硬连接数大于2的文件或目录
find   /home   -perm   0700                查权限为700的文件或目录
find   /tmp   -name tmp.txt   -exec cat {} \;
find   /tmp   -name   tmp.txt   -ok   rm {} \;

find    /   -amin    -10     # 查找在系统中最后10分钟访问的文件
find    /   -atime   -2        # 查找在系统中最后48小时访问的文件
find    /   -empty             # 查找在系统中为空的文件或者文件夹
find    /   -group   cat        # 查找在系统中属于 groupcat的文件
find    /   -mmin   -5         # 查找在系统中最后5分钟里修改过的文件
find    /   -mtime   -1       #查找在系统中最后24小时里修改过的文件
find    /   -nouser           #查找在系统中属于作废用户的文件
find    /   -user    fred     #查找在系统中属于FRED这个用户的文件

xargs 是一个强有力的命令,它能够捕获一个命令的输出,然后传递给另外一个命令,下面是一些如何有效使用xargs 的实用例子。
1. 当你尝试用rm 删除太多的文件,你可能得到一个错误信息:/bin/rm Argument list too long. 用xargs 去避免这个问题
find ~ -name ‘*.log’ -print0 | xargs -0 rm -f

2. 获得/etc/ 下所有*.conf 结尾的文件列表,有几种不同的方法能得到相同的结果,下面的例子仅仅是示范怎么实用xargs ,在这个例子中实用 xargs将find 命令的输出传递给ls -l
# find /etc -name "*.conf" | xargs ls –l

3. 假如你有一个文件包含了很多你希望下载的URL, 你能够使用xargs 下载所有链接
# cat url-list.txt | xargs wget –c

4. 查找所有的jpg 文件,并且压缩它
# find / -name *.jpg -type f -print | xargs tar -cvzf images.tar.gz

5. 拷贝所有的图片文件到一个外部的硬盘驱动 
# ls *.jpg | xargs -n1 -i cp {} /external-hard-drive/directory

05. 附录

参考:【Linux】一步一步学Linux系列教程汇总

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值