摘要:
本文将Linux中find、grep、xargs整理下,包括单个命令用法及混合命令用法。
一、find命令
find命令用于在目录层次结构搜索文件。man文件给出的find命令格式如下:
- find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
其中,[-H] [-L] [-P] [-D debugopts] [-Olevel]很少用[2],expression可以表示为-options [-print -exec -ok ...],简化展开后的find表达式如下:
- find path -option [-print][-exec command {} \;][-ok command {} \;]
注:
(1) -print后无需加"command {} \;"
(2) -exec或者-ok需要加"command {} \;"
(3) command与{}、{}与; 间需要空格
1.1 path
path是文件路径,可以是相对路径也可以是绝对路径,几个特殊符号如下:
. --从当前路径开始搜索
/ --从根目录开始搜索,即检索整个磁盘
~ --从用户目录开始搜索,如/home/jelline
1.2 option[1]

注:
(1)filename 当文件名是一个正规表达式时(比如所有头文件*.h),则需单引号或双引号括起来。
(2)prune 如果同时使用-depth选项,那么-prune选项将被find命令忽略
1.3 print & exec & ok
print --将匹配的文件输出到标准输出
exec --对匹配的文件执行该command所给出的shell命令
ok --与-exec功能相同,只不过在操作前要询用户
举例:
删除文件大小为零的文件:find ./ -size 0 -exec rm {} \; (还可以以这样做:rm -i `find ./ -size 0` 或 find ./ -size 0 | xargs rm -f &)
查当前目录下的所有普通文件 find . -type f -exec ls -l {} \;
1.4 例子
在当前目录及其子目录中查找任何扩展名为"c"的文件(不加-print也会输出结果)- find . -name "*.c"
- find . -perm 755 -print
- find /apps -path "/apps/bin" -prune -o -print
- find ~ -user sam -print
- find /apps -group gem -print
- find / -mtime -5 -print
- find /var/adm -mtime +3 -print
- find / -nogroup -print
- find /home -nouser -print
- find /etc -type d -print
- find . ! -type d -print
- find /etc -type l -print
- find /home/apache -size 100c -print
- find . -size +10 -print
- find / -name "CON.FILE" -depth -print
- find . -name "*.XC" -mount -print
二、grep
grep(Global Regular Expression Print)用于在指定文件搜索特定的内容,并将含有这些内容的行标准输出[3]。man文件给出的grep命令格式如下:
- grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
2.1 OPTIONS[2]
grep常用选项如下:
-?
同时显示匹配行上下的?行,如:grep -2 pattern filename同时显示匹配行的上下2行
-b,--byte-offset
打印匹配行前面打印该行所在的块号码
-c,--count
只打印匹配的行数,不显示匹配的内容
-f File,--file=File
从文件中提取模板空文件中包含0个模板,所以什么都不匹配
-h,--no-filename
当搜索多个文件时,不显示匹配文件名前缀
-i,--ignore-case
忽略大小写差别
-q,--quiet
取消显示,只返回退出状态0则表示找到了匹配的行
-l,--files-with-matches
打印匹配模板的文件清单
-L,--files-without-match
打印不匹配模板的文件清单
-n,--line-number
在匹配的行前面打印行号
-s,--silent
不显示关于不存在或者无法读取文件的错误信息
-v,--revert-match
反检索,只显示不匹配的行
-w,--word-regexp
如果被\<和\>引用,就把表达式做为一个单词搜索
-V,--version
显示软件版本信息
2.2 PATTERN
^ 锚定行的开始
如:'^grep'匹配所有以grep开头的行。
$ 锚定行的结束如:'grep$'匹配所有以grep结尾的行。
. 匹配一个非换行符的字符如:'gr.p'匹配gr后接一个任意字符,然后是p。
* 匹配零个或多个先前字符如:'*grep'匹配所有一个或多个空格后紧跟grep的行。 .*一起用代表任意字符。
[] 匹配一个指定范围内的字符,如'[Gg]rep'匹配Grep和grep。
[^] 匹配一个不在指定范围内的字符如:'[^A-FH-Z]rep'匹配不包含A-R和T-Z的一个字母开头,紧跟rep的行。
\(..\) 标记匹配字符如:'\(love\)',love被标记为1。
\< 锚定单词的开始如:'\\> 锚定单词的结束 如'grep\>'匹配包含以grep结尾的单词的行。
x\{m\} 连续重复字符x,m次如:'o\{5\}'匹配包含连续5个o的行。
x\{m,\} 连续重复字符x,至少m次如:'o\{5,\}'匹配至少连续有5个o的行。
x\{m,n\} 连续重复字符x,至少m次,不多于n次如:'o\{5,10\}'匹配连续5--10个o的行。
\w 匹配一个文字和数字字符也就是[A-Za-z0-9],如:'G\w*p'匹配以G后跟零个或多个文字或数字字符,然后是p。
\W w的反置形式,匹配一个非单词字符如点号句号等。\W*则可匹配多个。
\b 单词锁定符
如: '\bgrep\b'只匹配grep,即只能是grep这个单词,两边均为空格。
2.3 例子
通过管道过滤ls -l输出的内容,只显示以a开头的行
- ls -l | grep '^a'
显示所有以d开头的文件中包含test的行
- grep 'test' d*
显示在aa,bb,cc文件中匹配test的行
- grep 'test' aa bb cc
显示所有包含每个字符串至少有5个连续小写字符的字符串的行
- grep '[a-z]' aa
如果west被匹配,则es就被存储到内存中,并标记为1,然后搜索任意个字符(.*),这些字符后面紧跟着另外一个es(),找到就显示该行。如果用egrep或grep -E,就不用""号进行转义,直接写成'w(es)t.*'就可以了。
- grep 'w(es)t.*' aa
不区分大小写地搜索。默认情况区分大小写
- grep -i pattern files
只列出匹配的文件名
- grep -l pattern files
列出不匹配的文件名
- grep -L pattern files
只匹配整个单词,而不是字符串的一部分(如匹配'magic',而不是'magical')
- grep -w pattern files
匹配的上下文分别显示[number]行
- grep -C number pattern files
显示匹配 pattern1 或 pattern2 的行
- grep pattern1 | pattern2 files
显示既匹配 pattern1 又匹配 pattern2 的行
- grep pattern1 files | grep pattern2
三、xargs
3.1 概述
xargs(build and execute command lines from standard input),构造参数列表并运行命令,man文件给出的xargs命令格式如下:
- xargs [-0prtx] [-E eof-str] [-e[eof-str]] [--eof[=eof-str]] [--null] [-d delimiter] [--delimiter delimiter] [-I replace-str] [-i[replace-str]] [--replace[=replace-str]] [-l[max-lines]] [-L max- lines] [--max-lines[=max-lines]] [-n max-args] [--max-args=max-args] [-s max-chars] [--max-chars=max-chars] [-P max-procs] [--max-procs=max-procs] [--interactive] [--verbose] [--exit] [--no-run-if-empty] [--arg-file=file] [--show-limits] [--version] [--help] [command [initial-arguments]]
3.2 -exec与xargs区别
在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是"参数列太长"或"参数列溢出"。这就是xargs命令的用处所在,特别是与find命令一起使用[4]。
find命令把匹配到的文件传递给xargs(build and execute command lines from standard input)命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去[4]。
在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定[4]。
3.3 例子
查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件
- find . -type f -print | xargs file
整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中
- find / -name "core" -print | xargs echo "" >/tmp/core.log
在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限
- find . -perm -7 -print | xargs chmod o-w
用grep命令在当前目录下的所有普通文件中搜索hostnames这个词( \用来取消find命令中的*在shell中的特殊含义)
- find . -name \* -type f -print | xargs grep "hostnames"
参考资料:
[1] 博文《linux下find命令用法》
[2] 博文《linux中强大且常用命令:find、grep》
[3] 博文《linux find grep 查找文件命令》
[4] 文章《》