在使用Linux系统的时候我们常常需要对一些文本进行处理,但是有的时候文本特别长,所以我们需要找出我们需要的那些文本。grep命令就可以实现这个功能。
grep系列分为三种,分别是grep,egrep,fgrep,其中egrep和fgrep可以算是grep的衍生版,当grep加上一些特殊命令就变成了egrep和fgrep。这三种命令属于文本搜索工具,基于给定的文本进行模糊搜索。
grep的全名为Global search REgular expression and Print out the line,中文意思就是利用正则表达式进行全局搜索并将匹配的行显示出来。这个命令默认工作在贪婪模式下,也就是匹配所有可以匹配的内容,并显示出匹配到的字符所在行的全部内容。格式为grep [OPTIONS] PATTERN [FILE...]。
OPTIONS为grep的选项,常用选项有:
-i,--ignore:忽略文本字符的大小写;
这个功能能够用在当我们不想区分大小写的地方,比如:匹配所有以大、小写s字母
~]$ echo sadSdaaea | grep -i "s"
匹配结果:sadSdaaea
-v:反向匹配;最终显示结果是PATTERN不能成功匹配的行;
比如:先创建一个包含以下内容的文本文档“a” ~]$ cat a sd zx qw 然后使用匹配命令 ~]$ grep -v "s" a
匹配结果:
zx
qw
-c --count:匹配PATTERN这个条件的行数;
比如:可以使用上一个选项创建的“a”文件,然后执行命令: ~]$ grep -c "s" a
匹配结果:
1
-o --only matching:关闭贪婪模式,仅显示能够匹配的内容;
当我们在匹配的时候加上了这个选项,那么在显示匹配结果的时候只会显示匹配到的内容
比如:
grep -o "s" a
匹配结果:
s
这个结果匹配到的行应该是sd,但是由于加上了-o选项,所以只显示一个“s”字母
-q --quiet:安静模式,不输出任何匹配结果;
--color=auto:
-E:扩展的正则表达式,grep -E相当于egrep
-F --fixed-strings:grep -F相当于fgrep
-G --basic-regexp:基本的正则表达式
egrep -G相当于grep
fgrep -G相当于grep
-P per1-regexp:使用PCRE引擎;
-A --after-context=NUM:在显示PATTERN的同时显示其后面NUM行;
创建文件a,包含以下内容 ]$ cat a dasda efaf aew aa gaergaerg aerg aergaerg aer ga ergaeg
]$ cat a |grep-A 2 "aa"
匹配结果:
aa
gaergaerg
aerg
显示匹配到的内容,并显示其后头的两行
-B --before-context=NUM:在显示PATTERN的同时显示其前面NUM行;
]$ cat a |grep-B 2 "aa"
efaf
aew
aa
显示匹配到的内容,并显示其前头的两行
-C --context=NUM:在显示PATTERN的同时显示其前后NUM行;
]$ cat a |grep -C 2 "aa"
匹配结果:
efaf
aew
aa
gaergaerg
aerg
显示匹配到的内容,并显示其前头和后头的两行
PATTERN是过滤条件,是由正则表达式的元字符以及没有特殊含义的文本字符组成。正则表达式的元字符会被正则表达式的引擎解释为特殊含义。pcre——perl语言的正则表达式引擎是现在公认最完整的引擎。由一些正则表达式的元字符组成。比如:
字符匹配:
.:匹配任意单个字符;
]$ cat a |grep "."
匹配结果:
dasda
efaf
aew
aa
gaergaerg
aerg
aergaerg
aer
ga
ergaeg
[]:匹配范围内的任意单个字符;
]$ echo abcde | grep "[ace]"
匹配结果:
abcde
[^]:匹配指定范围以外的人以单个字符;
]$ echo abcde | grep "[^ace]"
匹配结果:
abcde
下列所有字符集都可以放于[]中用于匹配单个字符;
[:lower:]:小写字母
]$ echo 1a2D |grep "[[:lower:]]"
匹配结果:
1a2D
[:upper:]:大写字母
]$ echo 1a2D |grep "[[:upper:]]"
匹配结果:
1a2D
[:alpha:]:所有字母,同于[:lower:]和[:upper:]的组合
]$ echo 1a2D |grep "[[:alpha:]]"
匹配结果:
1a2D
[:digit:]:数字0-9:0 1 2 3 4 5 6 7 8 9
]$ echo 1a2D |grep "[[:digit:]]"
匹配结果:
1a2D
[:space:]:空格和制表符
匹配空白和制表符
[:alnum:]:字母与数字,同于[:alpha:]和[:digit:]的组合
]$ echo 1a2D |grep "[[:alnum:]]"
匹配结果:
1a2D
[:punct:]:特殊字符如:! " # $ % & ‘ ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` ~
]$ echo ‘[email protected]#‘ |grep"[[:punct:]]"(因为有特殊字符,所以使用强引用单引号将特殊字符变为普通字符)
匹配结果:
1a2D[email protected]#
[:blank:]:空白
[:xdigit:]:所有的十六进制数字:0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
]$ echo ‘[email protected]#‘ |grep"[[:xdigit:]]"
匹配结果:
1a2D[email protected]#
a-z:所有的小写字母;
]$ echo ‘[email protected]#‘ |grep "[a-z]"
匹配结果:
1a[email protected]#
A-Z:所有的大写字母
]$ echo ‘[email protected]#‘ |grep "[A-Z]"
匹配结果:
1a2D[email protected]#
0-9:标识所有十进制数字;
]$ echo ‘[email protected]#‘ |grep "[0-9]"
匹配结果:
1a2[email protected]#
次数匹配:该类字符之前的那个字符可以出现的次数;
]$ cat a | grep "[[:alpha:]]*"
匹配结果:
Dasda
Efaf
*:其前面的字符可以出现任意次;(0次,1次或多次)
\?:其前面的字符可有可无(0次或1次)
\+:其前面的字符至少出现一次(1次或多次)
\{m\}:起前面的字符必须出现m次;
]$ echo "aaaa" |grep"a\{3\}"
匹配结果:
aaaa
\{m,n\}:其前面的字符至少出现m次,至多出现n次;
\{,n\}:其前面的字符至少出现0次,至多出现n次;
\{m,\}:其前面的字符至少出现m次,多多益善;
组合起来的例子:
.*:任意字符出现任意多次
位置锚定字符:
行锚定:
行首锚定:^
]$ cat a dasda efaf aew aa gaergaerg ga ergaeg
]$ cat a | grep "^a"
匹配结果:
aew
aa
匹配以a开头的行
行尾锚定:$
]$ cat a
dasda efaf aew aa gaergaerg ga ergaeg
]$ cat a | grep "g$"
匹配结果:
gaergaerg
ergaeg
字锚定:
字首锚定:\<或\b
]$ echo "as is da" | grep"\<a"
匹配结果:
asis da
匹配以a字母开头的字符串
字尾锚定:\>或\b
\b:旧版本,不建议使用,因为有的时候会出问题,比如说前锚定和后锚定就不好区分
]$ echo "as is da" | grep"s\>"
匹配结果:
as is da
匹配以s字母结尾的字符串
在有一些情况下,我们可能需要一种例如匹配开头和结尾一样的字符串,如果仅仅使用上面的方法很难做到,所以现在有了分组和替换这个好东西。在进行匹配的时候,我们可以将一个前头匹配到的东西进行标记,然后在后边进行引用。具体的方法如下:
\(PATTERN\):把PATTERN所匹配到的字符当作一个整体处理
在一串的匹配元字符中,从左往右数,第几个“(”所包含的内容就是几,在后头可以使用\1,\2,\3...来进行引用。
PATTERN1\(pattern2\)pattern3\(pattern4\(pattern5\)\)
\1:pattern2
\2:pattern4 \(pattern5\)
\3:pattern5
在了解了分类之后,我们就可以使用它来进行实际的操作,例如:找到/etc/passwd中的uid与gid相同的行
grep ‘\(\<[[:digit:]]\+\>\).*\1‘ /etc/passwd
在匹配的时候我们还有可能用到或,例如匹配12或34,那么就需要用到“\|”这个符号了,但是请注意,这个符号会把两边的字符串当成一个整体,有的时候我们可能想写分别以大小写开头的例如:A\|american,但是这个方法是错误的,他会输出A或american,这个问题可以有两种方法来解决,一种是(A\|a)merican,第二种是将所有的都写出来:American\|american
接下来举个例子:
请找出ifconfig命令的执行结果中数值在100~255之间的整数; 第一位:1 2 第二位:0~9 0~4 5 第三位:0~9 0~9 0~5
答案:
ifcanfig|grep ‘\<\(1[0-9][0-9]\|2[0-4][0-9]\|25[0-5]\)\>‘
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
默认情况下,grep命令后面只允许有一个pattern,但是有的时候我们需要像或一样匹配多个我们想匹配的东西,那么此时需要使用-e选项,每个-e选项后头可以跟一个pattern作为参数。这样我们就可以同时匹配到不同的东西。为了方便,我们还可以将所需要的pattern写入到一个文件中,保证每行只有一个pattern,我们就可以使用grep -f file方式来实现多pattern匹配。
egrep和fgrep可以算是grep的衍生版,当grep加上一些特殊命令就变成了egrep和fgrep。egrep就是grep加上-E选项,它的作用就是使后头的匹配参数不需要转义即可生效,既可以使用基本的正则表达, 还可以用扩展表达式。而fgrep相当于grep加上-F选项,pattern中所有的字符都被当作文本字符来处理。