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、是否要修饰匹配内容呢?
它们用于展开或缩小(即是修改了)正则表达式匹配文本行的范围。修饰符包括了星号(*)、括号()、
反斜杠符号、问号。这些都可以称为修饰符。是用来修饰匹配内容的。