作用

linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户。

用法

grep [options] filename

主要参数

[options]主要参数:

-c:只输出匹配行的计数。

-i:不区分大小写(只适用于单字符)。

-h:查询多文件时不显示文件名。

-l:查询多文件时只输出包含匹配字符的文件名。

-n:显示匹配行及行号。

-s:不显示不存在或无匹配文本的错误信息。

-v:显示不包含匹配文本的所有行。

pattern正则表达式主要参数:

 

\:忽略正则表达式中特殊字符的原有含义。

^:行首锚定符,匹配正则表达式的开始行

$:行尾锚定符, 匹配正则表达式的结束行。

\<:词首锚定符,匹配正则表达式中单词开始

\>:词尾锚定符,匹配正则表达式中单词结束。

[ ]:单个字符,如[A]即A符合要求 。

[ - ]:范围,如[A-Z],即A、B、C一直到Z都符合要求 。

。:所有的单个字符。

* :所有字符,长度可以为0。

具体应用举例:

 

创建一个操作示例文件test.txt

cat > test.txt <<EOF

aa  bb cc

a1 a2 a3

ab abc acbdc

ccccccc

123456

11 22 33

123 123 123

aabbcc

test12

test13

sstets

EOF

 

 

  • 搜索有"test"的行,并输出行号

[senhua@localhost~]$ grep -n "ab" test.txt

3:ababc acbdc

8:aabbcc

 

  • 搜索没有test的行,并输出行号

[senhua@localhost~]$ grep -vn "test" test.txt

1:aa  bb cc

2:a1a2 a3

3:ababc acbdc

4:ccccccc

5:123456

6:1122 33

7:123123 123

8:aabbcc

11:sstets

 

  • 利用[]搜索集合字符

[] 表示其中的某一个字符 ,例如[ade] 表示a或d或e

搜索出以aa,ab开头的行

[senhua@localhost~]$ grep "a[ab]" test.txt

aa  bb cc

ababc acbdc

aabbcc

也可以写出

[senhua@localhost~]$ grep -E  "^aa|^ab" test.txt

aa  bb cc

ababc acbdc

aabbcc

补充 grep -E = egrep

可以用^符号做[]内的前缀,表示除[]内的字符之外的字符。

比如搜索test后没有2的字符串所在的行. 使用 'test1[^2]' 作搜索字符串

[senhua@localhost~]$ grep 'test1[^2]' test.txt

test13

注意匹配的是字符串后面的第一个字符,而不是所有的。若把'test1[^2]'换成'test[^2]'的话。就不符合要求

[senhua@localhost~]$ grep 'test[^2]' test.txt

test12

test13

[] 内可以用范围表示,比如[a-z]表示小写字母,[0-9] 表示0~9的数字, [A-Z] 则是大写字母们。[a-zA-Z0-9]表示所有数字与英文字符。当然也可以配合^来排除字符。

  • 搜索包含数字的行

[senhua@localhost~]$ grep -n '[0-9]' test.txt

2:a1a2 a3

5:123456

6:1122 33

7:123123 123

9:test12

10:test13

 

  • 字符位置匹配

行首与行尾字符 ^ $, ^ 表示行的开头,$表示行的结尾( 不是字符,是位置)那么‘^$’ 就表示空行,因为只有行首和行尾。

这里^与[]里面使用的^意义不同。它表示^后面的串是在行的开头。

比如搜索test在开头的行

[senhua@localhost~]$ grep "^test" test.txt

test12

test13

注意在MS的系统下生成的文本文件,换行会加上一个 ^M 字符。所以最后的字符会是隐藏的^M ,在处理Windows

下面的文本时要特别注意!

可以用cat dos_file | tr -d '/r' > unix_file 来删除^M符号。 ^M==/r

[senhua@localhost~]$ grep "^$" test.txt

任意一个字符. 与重复字符 *

在bash中*代表通配符,用来代表任意个 字符,但是在正则表达式中,他含义不同,*表示有0个或多个 某个字符。

例如 oo*, 表示第一个o一定存在,第二个o可以有一个或多个,也可以没有,因此代表至少一个o.

点. 代表一个任意字符,必须存在。 g??d 可以用 'g..d' 表示。 good ,gxxd ,gabd .....都符合。

 

  • 扩展正则表达式

扩展正则表达式是对基础正则表达式添加了几个特殊构成的。

它令某些操作更加方便。

比如我们要去除空白行和行首为 #的行, 会这样用:

[senhua@localhost~]$grep -v '^$' test.txt | grep -v '^#'

 

然而使用支持扩展正则表达式的egrep与扩展特殊符号 | ,会方便许多。

注意grep只支持基础表达式, 而egrep 支持扩展的, 其实 egrep 是 grep -E 的别名而已。因此grep -E 支持扩展正则。

那么:

[senhua@localhost~]$grep -v "^$|^#" test.txt

这里| 表示或的关系。 即满足 ^$ 或者^# 的字符串。

 

这里列出几个扩展特殊符号:

+, 于 . * 作用类似,表示 一个或多个重复字符。

?, 于 . * 作用类似,表示0个或一个字符。

|,表示或关系,比如 'gd|good|dog' 表示有gd,good或dog的串

(),将部分内容合成一个单元组。比如 要搜索 glad 或 good 可以这样 'g(la|oo)d'

()的好处是可以对小组使用+ ? * 等。

比如要搜索A和C开头结尾,中间有至少一个(xyz)的串,可以这样 : 'A(xyz)+C'

 

总结:

使用【grep】的时候,要注意:文件的通配符和正则表式的元字符有很多看似一样,但它们表示的特殊意义是不尽相同的。很容易混淆的。

使用【grep】搜索文本的时候,分析思路总结:

1、  分析匹配的内容

是做单词匹配呢、还是做字符(串)匹配呢。

   A、如果匹配的内容是单词的话,需要使用词首锚定符(\<)和词尾锚定符(\>)标识写在模式中的字串不是字符串而是单词。

   B、如果匹配的内容是字符(串)的话,就直接把匹配内容做为grep匹配模式就可以了,也就是字符串搜索。

2、  确定匹配的位置

   是行首还是行尾、词首、还是词尾、还是任意位置

   A、正则表达式提供了一些元字符来表示:在一行文本中要匹配的位置。

  如:行首锚定符(^)、行尾锚定符($)、词首锚定符(\<)、词尾锚定符(\>) 这些都统称为锚(目标点)。

  B、如果,正则表达式中没有这些锚定符的话,正则表达式在一行文本中要匹配的位置就是字符(串)。

3、是否要修饰匹配内容呢?

   它们用于展开或缩小(即是修改了)正则表达式匹配文本行的范围。修饰符包括了星号(*)、括号()、

   反斜杠符号、问号。这些都可以称为修饰符。是用来修饰匹配内容的。