Linux正则表达式
grep与正则表达式简介
文本处理工具中的三剑客--grep、sed、awk
grep,grep是根据模式过滤文本,并将符合模式的行显示出来,grep是一组工具集,包括了grep,egrep, fgrep。
sed,sed是stream editor,流编辑器,所以本质来说这是一个基于行文本编辑工具,也可以做过滤,但是如果用于做过滤的话,就有点大材小用了。
awk,Linux上的实现是gawk,awk其实是一个编程语言,它支持判断,循环等过程式语言的基本特性,awk主要特性既不是过滤文本,也不是编辑文本,而是能够将给定的数据以非常美观的格式输出的工具,所以他是一个文本报告生成器。
grep
grep是文本搜索工具,根据用户指定的"模式"对目标文本逐行进行匹配检查,打印匹配到的行
- 模式:有正则表达式字符及文本字符所编写的过滤条件
- 正则表达式:REGEXP,由一类特殊字符及文本字符所编写的模式,这些特殊字符不表示字符字面意义,而是表示控制或者通配的功能
正则表达式的类型
正则表达式又分为两类,基本正则表达式(BRE)和扩展正则表达式(ERE)
- BRE:grep默认情况下是支持基本正则表达式的
- ERE:egrep是用来支持扩展正则表达式,grep的-E选项也可以用来支持扩展正则表达式
fgrep表示不支持正则表达式。fast grep,如果支持正则表达式的话,必然要进行正则表达式解析,那就必然要耗费时间
grep的用法
# 基本语法
grep [OPTIONS] PATTERN [FILE...]
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]
- OPTIONS,命令选项
- PATTERN,模式
- FILE,目标文本,可以是一个或者是多个
grep的常用选项
1.指定使用正则表达式类型的选项
注意:其实我们使用一个grep就可以对grep家族(grep/egrep/fgrep)的命令进行调用
- -E:使用扩展正则表达式,相当于egrep
- -F:不使用正则表达式,相当于fgrep
- -G:使用基本正则表达式,默认行为
- -P:使用perl正则表达式
2.指定正则表达式行为的选项
- -i:匹配时,忽略字符大小写
- --color=auto:grep默认情况下是不显示匹配上的字符,所以最好加一个颜色
- -v: 反向选择,也就是说只显示没有被模式匹配到的整行内容
- -o:只显示被模式匹配到的字符串
- -q:静默模式,不输出任何信息,比如我们在写脚本的时候,只需要知道是否匹配上了即可,不需要输出,那么就有必要用这个选项
**grep匹配到了,那么grep执行的状态码是0,没有匹配到,执行状态码是1- -A:After-context,grep -A 2 root /etc/passwd:表示显示passwd文件中匹配到了root的行,以及匹配到的行之后的两行(如果后面的行已经不够了,尽量显示)
- -B:Before-context,grep -B root /etc/passwd:表示显示passwd文件中匹配到了root的行,以及匹配到的行之前的两行(如果前面的行不够了,尽量显示)
- -C:Context,grep -C root /etc/passwd:表示显示passwd文件中匹配到了root的行,以及匹配到的C前后两行(尽量显示)
Title:将grep重命名,自己就不用每次都设定颜色了。
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias grep='grep --color=auto'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
基本正则表达式BRE
BRE的元字符
元字符,是指不代表字符本身的意义,而是表示通配和控制。grep中正则表达式的元字符根据功能可以分为字符匹配,匹配次数,位置锚定和分组
如果在匹配的模式中出现了元字符了,那么就要用引号引起来,单引号表示强引用,双引号为弱引号,所以双引号引起来的话,里面有变量也会被替换成变量的值,然后做匹配。
1.字符匹配
- . :匹配任意单个字符;
- [] :匹配指定字符范围内的任意单个字符
- [^] : 取反,匹配指定字符范围外的任意单个字符
注意:可以使用的字符范围有①字符集合:[:digit:], [:lower:], [:upper:], [:punct:];②特殊符号:[:space:], [:alpha:], [:alnum:];③数字和字母,所以我们在使用字符匹配时,还需要加上元字符,例如:[[:alpha:]]表示匹配字母
2.匹配次数
匹配次数用在字符匹配后面,表示控制字符匹配的次数
- *:*表示匹配其前面的字符任意次,0到n次;例如:x*y,表示匹配以y结尾,前面有0到n个x,默认情况下,正则表达式工作在贪婪模式下。*本身是不代表任意字符的,只是代表任意次数,所以类似*y这样是没有意义的。这和glob中的*通配符的意义是不同的。glob中ll *.txt还是可以查询到.txt结尾的文件的
- ?:匹配其前面的字符1次或0次(问号是在'',所以一定要用转义字符将其转义出来)。这也可以和glob作一个比较,在glob中是不用放到''内的,所以不用进行转义
- +:匹配其前面的字符至少1次
- {n}:匹配前面的字符n次,一定要是n次
- {n,}:匹配前面的字符至少n次
- {,n}:匹配前面的字符至多n次,即0到n次
- {m,n}:匹配其前面的字符至少m次,至多n次,({}必须加转义字符)例如:grep 'a.{1,3}b'也就是说a和b之间最多可以3个a,最少需要出现1个a
关于匹配次数的例子
{1,} :最少重复一次,没有上限
{0,3}:0-3次
{3}:固定的3次
3.位置锚定
- ^:行首锚定,必须是写在左侧
- $:行尾锚定,必须写在行尾
注意:如果^root$那么表示这一行,必须只能是root,另外^$表示是一个空行,^[[:space:]]*$表示匹配空行或者是空白字符的行
- < 或者 :词首锚定,用于单词模式的左侧,
- >或者:词尾锚定,用于单词模式的尾部,
- <pattern>:单词锚定,例如:grep '<root>' /etc/passwd
4.分组
- (pattern):表示这个pattern当做一个整体来看待,例如:grep '(root)+' /etc/passwd,匹配passwd文件中含有root字符串至少一次的行
这里的分组和上面的单词锚定有本质的区别,单词锚定是root前后必须都是特殊字符,像//、空格、:等,而(root)+则表示root是不可分割的整体,而且其后面可以根据指定的匹配次数表示连续的重复的出现root的情况- 后向引用:引用前面的分组括号中模式所匹配到的字符,不是模式本身。
分组括号中的模式所匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量在grep中被命名为:1,2,3...,在其他语言中可能会不一样。
其中1表示:从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符
例如:(ab+(xy)),此时的1是ab+(xy),第一个左侧括号到其结束的右括号,2是xy
扩展正则表达式元字符ERE
ERE的元字符
ERE中的元字符兼容BRE中的元字符,不过BRE中需要使用来转义的元字符,在ERE中可以不用了
1.字符匹配
- . :匹配任意单个字符;
- [] :匹配指定字符范围内的任意单个字符
- [^] : 取反,匹配指定字符范围外的任意单个字符
2.匹配次数
匹配次数用在字符匹配后面,表示控制字符匹配的次数
- *:*表示匹配其前面的字符任意次,0到n次;
- ?:匹配其前面的字符1次或0次在扩展正则表达式中,可以不用使用来进行转义。
- +:匹配其前面的字符至少1次
- {n}:匹配前面的字符n次,一定要是n次
- {n,}:匹配前面的字符至少n次
- {,n}:匹配前面的字符至多n次,即0--n次
- {m,n}:匹配其前面的字符至少m次,至多n次,({}必须加转义字符)例如:grep 'a.{1,3}b'也就是说a和b之间最多可以3个a,最少需要出现1个a
关于匹配次数的例子
{1,} :最少重复一次,没有上限
{0,3}:0-3次
{3}:固定的3次
3.位置锚定
- ^:行首锚定,必须是写在左侧
- $:行尾锚定,必须写在行尾
- < 或者 :词首锚定,这里的是要保留的
- >或者:词尾锚定
- <pattern>:单词锚定,例如:grep '<root>' /etc/passwd
4.分组
- (pattern):分组这里的也可以不用
- 后向引用:后向引用这边的1,2...还是一样的
5.或者
- a|b:表示匹配a或者b
注意:C|cat:表示的是匹配C或者cat,这种对称形式的模式表示"或者"时,表示的是要么匹配左边,要么匹配右边;(C|c)at表示匹配cat或者Cat