《LINUX与UNIX SHELL编程指南》读书笔记(二)
时间:2007-09-18 来源:wflai
第 2 章 使用 find 和 xargs
1.有时可能需要在系统中查找具有某一特征的文件(如文件权限、文件属主、文件长度、文件类型等)。find是一个非常有效的工具,它可以递归式遍历当前目录甚至于整个文件系统(本地和网络文件系统)来查找某些文件或目录,只要你具有相应的文件或目录的权限。
2.find 命令的使用
1) Usage : find [path_name ...] [expression]
2) path_name : 用于指定要搜索的目录,可以是以空格分隔的多个目录路径的列表。如果省略此参数,默认使用当前目录。
3) expression : 用于指定搜索的方式、条件和要执行的操作等。如果 expression 省略,则默认使用 -print 作为 expression。expression 可由 4 类项目组成:
① OPTION(选项) : 用于指定 find 命令的搜索方式,一般把 OPTION 放在 expression 的开头。
② TEST(测试) : 用于指定 find 命令的检索条件,只有符号条件的文件才会被指定的 ACTION 处理。
③ ACTION(操作) : 用于指定对 find 的搜索结果执行的操作。省略 ACTION 时预设为 -print。
④ OPERATOR(运算) : 对 TEST 或 ACTION 进行与、或、非 等运算。
4) find 在执行时,一般会将第 1 个"-"字符之后的命令行参数都看作 expression,把之前的参数都看作为要搜索的路径。
3.常用的 OPTION 项目
0) OPTION 项目可以省略,find 默认从指定路径目录开始递归地向下层子目录搜索。
1) -depth : 在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
2) -maxdepth level : 进入指定的目录下层目录搜索时,最深不超过 level(一个非负整数)层。
eg: find . -maxdepth 0 -name "1" // 只在当前目录而不向下层子目录搜索名为"1"的文件或目录
3) -follow : 如果 find 命令遇到符号链接文件,就跟踪至链接所指向的文件。
4) -mount : 不搜索其它文件系统上的目录(不跨越文件系统 mount 点)。
5) -daystart : 从当日起始时开始而不是从 24 小时之前开始计算时间(如-amin, -atime, -cmin, -ctime, -mmin 和 -mtime )。
6) -noleaf : 不为"目录中子目录数量比硬链接数少 2"这种假设做优化。这个选项在搜索那些不遵循 UNIX文件系统链接约定的文件系统(比如 CD-ROM,MS-DOS 文件系统或 AFS 卷的加载点)时使用。在普通的 UNIX 文件系统中,每个目录至少有两个硬链接: 它的名字和它的'.'条目。另外,它的每个子目录(假如有的话)还会各有一个'..'链接到它。在 find 检索一个目录时,发现子目录数比它的链接数少二时,它就知道目录中的其他条目并非目录(而是目录树中的叶(`leaf')节点)。除非需要检索的是这个叶节点,否则没必要去处理它。这样可以带来很大的搜索搜索速度的提升。
4.常用的 TEST 项目
0) 在 TEST 项目的一些选项中有时会使用数字,数字 N(非负整数)可以以 3 种形式给出:
+N 表示比 N 大, -N 表示比 N 小, N 表示正好是 N
1) -name PATTERN : 查找文件名符合模式 PATTERN(一般要加双引号)的文件,也可直接使用文件名。
eg: find . -name "[a-z][a-z][0-9][0-9].txt" -print // 此命令可以返回名为 ax37.txt 的文件
2) -empty : 查找空白文件,它可以是一般文件或目录。
3) -lname PATTERN: 只查找符合 PATTERN 的符号链接文件。
4) -iname 和 -ilname : 分别与 -name 和 -lname 类似,只是不区分大小写。
5) -regex PATTERN : 查找完整文件名符合模式 PATTERN 的文件。
6) -type C : 查找某一类型的文件。C 可以是 b c d p l s f (块设备 字符设备 目录 命名管道 符号链接
socket 正规文件)。
eg: find ~ -type l // 此命令返回当前用户的主目录内所有的符号链接文件的文件名
7) -size N[bckw] :查找使用 N 个单位空间的文件,可以使用 b(块,512 字节) c(字节) k(KB) w(2 字节)为
单位,不带单位时预设为 b。
eg: find ~ -size +100k -size -1024k // 此命令返回文件尺寸大于 100k 小于 1M 的文件的文件名
8) -fstype FSTYPE : 查找位于某一类型文件系统中的文件,如 vfat ext3 nfs 等
9) -user USERNAME : 查找文件属主为 USERNAME 的文件。
-uid UID : 查找文件属主的 uid 为 UID 的文件。
10) -group GROUPNAME : 查找文件所属组为 GROUPNAME 的文件。
-gid GID : 查找文件所属组的 gid 为 GID 的文件。
11) -nouser : 查找无有效属主的文件,即该文件的属主在/etc/passwd 中不存在。
-nogroup : 查找无有效所属组的文件,即该文件所属的组在/etc/groups 中不存在。
12) -perm MODE : 查找文件的权限设置等于 MODE 的文件。MODE 前可加"+"或"-",表示权限设置比 MODE 宽松)
或更严格。
13) -anewer FILENAME : 查找其存取(access)时间比文件 FILENAME 的修改时间更接近现在的文件。
-cnewer FILENAME : 查找其状态改变(change)时间比文件 FILENAME 的修改时间更接近现在的文件。
-newer FILENAME : 查找其内容修改(modify)时间比文件 FILENAME 的修改时间更接近现在的文件。
-amin N : 查找在指定时间(N 为分钟)被存取过的文件。
-cmin N : 查找在指定时间(N 为分钟)更改过文件状态的文件。
-mmin N : 查找在指定时间(N 为分钟)修改过数据内容的文件。
-atime N : 查找在指定时间(N 为天)被存取过的文件。
-ctime N : 查找在指定时间(N 为天)更改过文件状态的文件。
-mtime N : 查找在指定时间(N 为天)修改过数据内容的文件。
注: 上面这些选项分别涉及到文件的 3 种时间: 文件存取时间(access)、文件状态改变时间(status change) 和 文件内容修改时间(modify),也就是在 ls -l 命令输出中显示的时间。
5.常用 ACTION
1) -print : 以完整文件路径名的形式将 find 的搜索结果显示到标准输出,以 NEWLINE 分隔各个文件名。
2) -ls : 以"ls -l"命令的格式将 find 的搜索结果显示到标准输出。
3) -exec CMD {} \; : 把 find 的搜索结果作为 shell 程序 CMD 的文件名参数,并执行 CMD 程序。
eg: find /logs -mtime +5 -exec rm -rf {} \; // 删除/logs 目录中更改时间在 5 日以前的文件
4) -ok CMD {} \; : 同上,是一种更安全的模式,在执行每个命令前,会提示用户来确定是否执行。
6.常用的 OPERATOR
1) EXPR1 EXPR2 或 EXPR1 -a EXPR2 或 EXPR1 -and EXPR2 : 把 2 个 EXPR 相与。
eg: find ~zqf -size +10k -name "*.c" // 从 zqf 的主目录开始搜索大于 10kB 的 C 源程序文件
2) EXPRT1 -o EXPR2 或 EXPR1 -or EXPR2 : 把 2 个 EXPR 相或。
eg: find . -name "*.c" -or -name "*.cpp" // 从当前目录开始搜索 C 或 C++源程序文件
3) ! EXPR 或 -not EXPR : 对 EXPR 取反。
eg: find ~zqf ! -user zqf // 查找 zqf 的主目录中属主不是 zqf 的文件或目录
4) ( EXPR ) : 当出现多个 OPERATOR 时,用来改变 OPERATOR 的运算顺序。
eg: find . ! \( -user zqf -name "*.awk" \)
7.xargs
1) Usage: xargs CMD (从管道中获取 CMD 命令的参数)
2) xargs 常常与 find 命令一起使用,用于取代 find 的-exec 参数。有几个原因:
① find 的-exec 参数有很多局限。比如,递给 exec 的命令长度有限制,在某些系统上-exec 参数只能调用很少的 shell 命令等。
② 某些系统上-exec CMD 选项会为 find 的搜索结果中的每一个文件名启动一个 CMD 进程,而不是把搜索结果作为一个参数文件列表整个传给 CMD 程序,当搜索结构很多时,会严重影响系统性能。xargs CMD 把从管道获取的参数作为一个参数列表一次传给