02 January 2014
所有的linux 命令都不会超出man page,所以你看到的所有文档都是man的一个子集。对命令行掌握的标准是你可以直接看man来学习linux 命令。但是,这需要你具备很多基础知识。对于初学者,基本一头雾水,我也曾经迷茫过,所以,自己的努力整理了这份文档,使得你能从开始到通过man来学习linux命令很平滑地过渡。本文档有很多实例方便初学者学习,也可以作为man grep的速查版。

Grep

全称global search regular expression(RE) and print out the line。是一种强大的文本搜索工具,它基于匹配模式搜索文本,并把匹配的行打印出来,支持基本正则表达式(RE),也支持其扩展集(ERE),是linux下文本处理的利器之一。

grep 命令格式

grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]

  1. 输入字符串作为参数,最好双引号括起,以防被误解为shell命令。
  2. 在调用变量时,也使用双引号括起 “$MYSTR”
  3. 使用正则[PATTERN]是,应使用单引号括起 ‘49[32]’

参数

####匹配方式选择

-E   : 启用扩展正则表达式(ERE),可使用扩展元字符。
-F   : 搜索固定字符,不支持正则表示式。主要是在简单搜索中增快搜索速度。
-G   : 启用基本正则表达式(BRE)。
-P   :启用 perl 的正则表达式。(PCRE)

####示例 grep -E “.*test\b” *.doc
grep -F “test” *.doc
grep –v “test” data.txt

####匹配控制

-e PATTERN : 这个选项主要是当你一个RE无法完全表达时的一种选择。你可以通过-e 来指定多个表达式,只要满足其中一个表达式就输出。防止你对一个文件grep多次。比如有file,我要提取其中含有"come"或"here"的行,grep -e "come" -e "here" file 即可。

-f FILE :  从文件 FILE 中获取模式,每行一条匹配。空文件含有0个模式,因此不匹配任何东西。 

-i  : 不区分模式 PATTERN 和输入文件中的大小写。

-v :  只选择不匹配的行。 

-w :  首先单词字符只能是字母、数字、下划线。除此之外的字符都是非单词字符。这个选项只能匹配完整的单词,这个单词的前一个字符和后一个字符都必须是非单词字符。比如,有一个文件file:
        1 workword 
        2 _word 
        3 word2
        4 word*
        5 word-
grep -w "word" file. 只能匹配第4、5行。

-x : 选择能匹配完整一行的匹配。比如,有一个文件file:
        1 come here
        2 come
        3 here come here
    grep -x "come" file 匹配第2行。
    grep -x "come.*" file 匹配第1、2行。
    grep -x ".*come.*" file 匹配全部。

####示例 grep –i “ignore” data.txt echo “aaaaaa” |grep -x aaa

####输出控制 -c : 只打印有多少行匹配。不显示匹配的内容。

-NUM : 同时显示匹配行上下的NUM行,如:grep -2 pattern filename同时显示匹配行的上下2行。

--colour[=WHEN] : 在匹配的行周围以 GREP_COLOR 环境变量中指定的记号来标记。WHEN 可以是 `never', `always', 或是 `auto'。 一般在.bashrc文件中会有alias grep = 'grep --color=auto',赶快去看下。

-L :与-l相反。打印不匹配的文件名。一般和find一起发功。

-l : 打印出匹配的文件名而不是行。这个选项经常与find结合,比如你的/etc下搜索 linux 字符,很可能有很多行,但是也许文件数并不多,所以,可以
    find /etc | xargs grep -l "dhcp"
    这样就可以快速定位文件,不会被太多的匹配行亮瞎你的双眼。

-m NUM : 匹配NUM次,后停止搜索。

-o : 只显示匹配的内容,而不是整行。

-q : 什么也不输出,即使发生错误,只要有满足匹配模式的行,就返回0。如果没有满足匹配模式的行,返回123。

-s : 忽略错误和遇到不可读的文件时的信息。和-q都是不可移植的选项。建议用2> /dev/null 代替。

####示例 grep –c “test” data.txt grep -l ‘root’ test test2 testbak DAta cat test |grep -m 1 zhang

####输出行前缀控制

-b : 在匹配行前面增加当前行在搜索文件的字节偏移量。 

-h : 当搜索多个文件时,不显示匹配文件名前缀。与find结合使用

-H : 当搜索多个文件时,显示匹配文件名前缀,这是默认的选项。 与find 结合使用

--label=LABLE : 待定

-n : 显示匹配行及行号 

-T : 对输出的内容,按列以tab隔开。对于后续用awk处理此选项非常有用。此外结合-n -h 可以使得输出为 文件名:行号:匹配行内容。

-u : 在匹配行前面增加当前行在搜索文件的字节偏移量。使用与Unix-Like文件,对于MS-DOSl类文件没有影响。

-Z : 输出一个全零字节 (ASCII 码中的 NUL 字符) 而不是一般情况下输出在文件名之后的字符。例如, grep -lZ 在每个文件名之后输出一个全零字节而不是普通的新行符。这个选项使得输出清楚明白,即使文件名的表示中包含特殊字符比如新行符。这个选项可以与命令 find -print0, perl -0, sort -z, 和 xargs -0 一起使用,来处理任意的文件名,即使是那些含有新行符的文件名。 

####示例 cat test |grep -b zha
grep -h ‘root’ test test2 testbak
grep -H ‘root’ test test2 testbak

####行内容控制 -A NUM : 打印匹配行之后NUM行

-B NUM : 打印匹配行之前NUM行

-C NUM : 匹配行前后NUN行

Note : 当与-o合用,此选项仍然无效。

####示例 cat test |grep -A 3 root

####文件和目录选择

-a : 把二进制当作文本文件处理

--binary-files=TYPE : 如果一个文件的起始几个字节表明文件包含二进制数据,那么假定文件是 TYPE 类型的。默认情况下, TYPE 是 binary ,并且 grep 一般会输出一个一行的消息说一个二进制文件匹配,或者如果没有匹配的话就没有消息输出。如果类型 TYPE 是 without-match ,那么 grep 假定二进制文件不会匹配;这样 -I 选项等价。如果类型 TYPE 是 text ,那么 grep 将一个二进制文件视为文本文件来处理;它与 -a 选项等价。 警告: grep --binary-files=text 可能会输出二进制的无用内容。如果输出设备是一个终端,并且终端的驱动将这些输出中的一些当作命令,可能会带来恶劣的副作用。 

-D ACTION : 如果输入文件是一个设备,FIFO 或是套接字 (socket) ,使用动作 ACTION 来处理它。默认情况下,动作 ACTION 是 read ,意味着设备将视为普通文件那样来读。如果动作 ACTION 是 skip ,将不处理而直接跳过设备。 注意,当你处理特殊文件时候要小心。

-d ACTION : 如果输入文件是一个目录,使用动作 ACTION 来处理它。默认情况下,动作 ACTION 是 read ,意味着目录将视为普通文件那样来读。如果动作 ACTION 是 skip ,将不处理而直接跳过目录。如果动作 ACTION 是 recurse , grep 将递归地读每一目录下的所有文件。这样做和 -r 选项等价。 

--exclude=GLOB : 不查询匹配GLOB模式文件,即支持 *、?、[...],\字符 防止解析特殊字符。不管用。

--exclude-from=FILE : 将上面的匹配模式写在FILE中。仍然支持GLOB模式。不管用。

--exclude-dir=DIR : 不查询匹配模式文件。不管用。

-I : 与--binary-files=without-match相同

--include : 只查询该模式文件

-r : 递归地读每一目录下的所有文件。在命令行模式下会跟踪符号文件,这样做和 -d recurse 选项等价。 

-R : 递归地读每一目录下的所有文件,会跟踪符号文件。

示例 grep test -R /tmp/test/mytest

####其他选项 –line-buffered : 使用行缓冲,或降低性能。

--mmap : 如果可能的话,使用 mmap(2) 系统调用来读取输入,而不是默认的 read(2) 系统调用。在一些情况下, --mmap 提供较好的性能。但是,如果一个输入文件在 grep 正在操作时大小发生变化,或者如果发生了一个 I/O 错误, --mmap 可能导致未定义的行为 (包括core dumps)。 

-U : 将文件视为二进制。默认情况下,在 MS-DOS 和 MS-Windows 系统中, grep 通过从文件中读取头部的 32kB 内容来判断它的文件类型。如果 grep 判断文件是一个文本文件,它将原始文件内容中的 CR 字符去除 (使得含有 ^ 和 $ 的正则表达式可以正常工作)。指定 -U 将不进行这些工作,而使所有文件保持不变地读取并传递给匹配机制。如果文件是一个以 CR/LF 换行的文本文件,这样作将导致一些正则表达式失败。这个选项在 MS-DOS 和 MS-Windows 之外的系统中无效。

-z : 将输入当做行的集合,每个行以 0 btye 代替新行,与 -Z 相同,这个选项可以被 sort -z 来处理二进制文件。

正则表达式

NOTE: 正则表达式可以用一本书来写,下面只是简介。

^ : 行的开始 如:'^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开头的单词的行。 

\> : 单词的结束,如'grep\>'匹配包含以grep结尾的单词的行。 

x\{m\} : 重复字符x,m次,如:'0\{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的反置形式,匹配一个或多个非单词字符,如点号句号等。

\b : 单词锁定符,如: '\bgrep\b'只匹配grep。

###正则表达式扩展集(ERE)
+ : 匹配一个或多个先前的字符。如:’[a-z]+able’,匹配一个或多个小写字母后跟able的串,如loveable,enable,disable等。

? : 匹配零个或多个先前的字符。如:'gr?p'匹配gr后跟一个或没有字符,然后是p的行。

a|b|c : 匹配a或b或c。如:grep|sed匹配grep或sed 

() : 分组符号,如:love(able|rs)ov+匹配loveable或lovers,匹配一个或多个ov。

x{m},x{m,},x{m,n} : 作用同x\{m\},x\{m,\},x\{m,n\} 

###POSIX字符类 为了在不同国家的字符编码中保持一至,POSIX(The Portable Operating System Interface)增加了特殊的字符类,如[:alnum:]是A-Za-z0-9的另一个写法。要把它们放到[]号内才能成为正则表达式,如[A- Za-z0-9]或[[: alnum:]]。在linux下的grep除fgrep外,都支持POSIX的字符类。

[:alnum:] : 文字数字字符 
[:alpha:] : 文字字符 
[:digit:] : 数字字符 
[:graph:] : 非空字符(非空格、控制字符) 
[:lower:] : 小写字符 
[:cntrl:] : 控制字符 
[:print:] : 非空字符(包括空格) 
[:punct:] : 标点符号 
[:space:] : 所有空白字符(新行,空格,制表符) 
[:upper:] : 大写字符 
[:xdigit:] : 十六进制数字(0-9,a-f,A-F) 

###正则表达式高级–捕获

使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

NOTE: 分组0对应整个正则表达式,实际上组号分配过程是要从左向右扫描两遍的:第一遍只给未命名组分配,第二遍只给命名组分配--因此所有命名组的组号都大于未命名的组号 你可以使用(?:exp)这样的语法来剥夺一个分组对组号分配的参与权.

####常用: (exp) : 匹配exp,并捕获文本到自动命名的组里 (?exp) : 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp) (?:exp) : 匹配exp,不捕获匹配的文本,也不给此分组分配组号

####零宽断言 (?=exp) : 匹配exp前面的位置 (?<=exp) : 匹配exp后面的位置 (?!exp) : 匹配后面跟的不是exp的位置 (?<!exp) : 匹配前面不是exp的位置

####注释
(?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。难以理解?请看示例:

\b(\w+)\b\s+\1\b 

可以用来匹配重复的单词,像go go, 或者kitty kitty。这个表达式首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)

你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+)),这样就把\w+组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样: \b(?<Word>\w+)\b\s+\k<Word>\b

####示例 grep ‘48[34]’ data.txt

grep ‘^[^48]’ data.txt 开头不是4,8的

grep ‘[Ss]ept’ data.txt

grep ‘^[0-9][0-5][0-6]’

grep ‘4\{2,\}’ data

grep ‘^$’ data

grep ‘\.’ myfile

grep ‘5[[:upper:]] [[:upper:]]’ data 

环境变量

####Locale 通过依次检查LC_ALL LC_foo LANG来决定locale,如果都没有则以C locale为locale.

####GREP_OPTIONS 这个变量的作用是当你输入grep的时候默认帮你添加的选项。比如GREP_OPTIONS是–colour=auto,那么,你输入grep的时候,相当于”grep –colour=auto”,如果有多个选项以空格分开。当一个选项中包含空格的时候,可以用\ 来表示。比如 GREP_OPTIONS=”-n -A\ 2 –colour=auto”。

####GREP_COLOR 对匹配的非空字符高亮显示控制。ms,mt,mc与GREP_COLORS兼容,并且优先级更高。m默认01;31,即红色的字作为前景色。

####GREP_COLORS 默认:ms=01;31:mc=01;31:sl=:cx=:fn=35:ln=32:bn=32:se=36,rv和ne布尔值忽略。 sl : 默认为空,整个选中的行遵循SGR子集。当没有-v的时候,输出匹配行,当有-v的时候,输出不匹配的行。rv和-v一起,输出匹配的行。 cx : 默认为空,整个选中的行遵循SGR子集。与sl正好相反。 rv : 布尔值,和-v选项一起可以交互rv和sl的意义。

mt=01;31 : 在匹配的非空行中遵循SGR子集。 默认红色的字作为前景色
ms=01;31 : 在选中的非空行中遵循SGR子集。 默认红色的字作为前景色
mc=01;31 : 在内容的非空行中遵循SGR子集。 默认红色的字作为前景色
fn=35 : 在内容行文件名前缀遵循SGR子集。默认紫色(magenta)前景和终端默认背景。
ln=32 : 在内容行行号遵循SGR子集。默认绿色(green)前景和终端默认背景。
bn=32 : 在内容行byte偏移前缀遵循SGR子集。默认绿色(green)前景和终端默认背景。
se=36 : 选中区的分隔符`:`,内容域的`-`,和邻行的组`--`. 默认青色(cyan)前景和终端默认背景。

ne : 布尔值,默认false。

SGR字符集是十进制整数,可以同;连接起来。

LC_ALL LC_COLLATE, LANG

定义[a-z]中代表的意义。

LC_ALL LC_CTYPE, LANG

定义字符的意义。比如那个字符表示空格,

LC_ALL LC_MESSAGES, LANG

grep 中 message 的语言。默认English。

POSIXLY_CORRECT

如果设置,执行 POSIX.2 请求。

N_GNU_nonoption_argv_flags_

在GUN c库和POSIXLY_CORRECT情况下可用。

返回值

0 :找到匹配

1 :没有找到匹配

>2 : 错误

参考文档

 man grep
《正则指引》  余晟