文本三剑客之 grep

文本三剑客之 grep

正则表达式是一钟特殊的字符串模式,用于匹配一组字符串,正则表达式的宗旨是文本资源为我所用。正则表达式是vim, grep, sed, awk等重多强大文本处理工具的重要组成部分。正则表达式因”坑”多而闻名,其实是对正则的掌握不到位所致。各工具中正则的语法有所差别,我们将介绍在Linux系统上处理文本的三个重要工具grep, sed, awk。
本文首先介绍grep


grep, sed, awk

  • grep(包括egrep): 主要用来过滤文本
  • sed: 文本编辑
  • awk: 文本分析处理

正则表达式分类
在Linux系统中,正则表达式分为两类:

  • 基本正则表达式
  • 扩展正则正则表达式

正则表达式的组成
正则表达式一般由匹配字符次数控制字符位置控制字符分组字符普通字符组成,除了普通字符外的字符都叫元字符,元字符不再表示字符字面意义,而表示控制或通配功能。


基本正则表达式

字符匹配

用来表示通配功能

字符 作用
. 匹配任意个字符
[] 匹配指定范围内的任意个字符
[:lower:] 匹配小写字母, 同a-z,但与匹配路径的通配符不一样喔
[:upper:] 匹配大写字母,同A_Z
[:alph:] 匹配所有大小写字母,同a-z,A-Z
[:digit:] 匹配数字,同0-9
[:xdigit:] 匹配十六进制数字
[:alphnum:] 匹配所有字母和数字, 同a-z,A-Z,0-9
[:blank:] 匹配空白字符(空格和制表符)
[:space:] 匹配水平或垂直空白字符(比[:blank:]包含的范围广)
[:cntrl:] 匹配不可打印的控制字符(退格、删除等)
[:print:] 匹配可打印字符
[:punct:] 匹配标点符号
[:graph:] 匹配可打印的非空白字符

匹配次数

上面的元字符均只能匹配单个字符,若要匹配重复的多个字符,则需加上控制次数的元字符,控制次数的字符用在要指定次数的字符后面,用于指定前面字符的重复次数。

控制次数的元字符 作用
* 任意次数,包括0次,默认是贪婪模式,尽可能长的匹配,.* 任意长度,任意字符
\? 0次或1次
\+ 1次及以上
\{m,n\} m到n次, 包括m和n次
\{,n\} m次以上,包括m次
\{,n\} n次以下,包括n次

位置锚定

有时我们需要定位所匹配字符出现的位置,就使用位置锚定字符

字符 作用
^ 行首锚定,用于模式的最左侧
& 行尾锚定,用于模式的最右侧,^&匹配空白行,该行什么字符都没有,包括不可见字符才能匹配
\<,\b 词首锚定,用于单词的左侧
>,\b 词尾锚定,用于单词的右侧,\匹配单个单词

分组

有时我们需要将多个字符作为一个整体进行匹配处理,这时就可用分组\( \),这些被括号所括起来的模式所匹配到的内容被正则表达式引擎记录与内部的变量中,后序我们就可以通过这些变量名来引用所匹配到的字字符串

这些变量被命名为\1, \2, \3 …
\1: 从左到右第一个分组括号与之配套的括号所括起来的模式所匹配到的内容
\2: 从左到右第二个分组括号与之配套的括号所括起来的模式所匹配到的内容
。。。

逻辑或
\| :

  • a\|b a或b
  • ax\|b ax或b
  • a\(x\|b\) ax或ab

扩展正则表达式

扩展正则表达式除了控制次数的元字符与基本正则表达式不一样外,其它相同

字符 作用
* 任意次数,包括0次,默认是贪婪模式,尽可能长的匹配,.* 任意长度,任意字符
? 0次或1次
+ 1次及以上
{m,n} m到n次, 包括m和n次
{m,} m次以上,包括m次
{,n} n次以下,包括n次

grep

grep 通过模式去匹配文本,并打印匹配到的行,模式为正则表达式或普通字符

  • grep [options] PATERN files
  • 常用选项

–color=auto #对匹配到的文本加颜色
-i #匹配的时候忽略字母大小写
-n #显示所匹配到的行在原文中的行号
-c #统计匹配到的行数
-v #显示未匹配到的行
-o #仅显示匹配到的字符串
-q #静默模式,不输出任何信息,可以使用echo $?查看是否匹配成功
-A NUM #after,显示匹配到的行及后NUM行
-B NUM #before,显示匹配到的行及前NUM行
-C NUM #context,显示匹配到的行及前后各NUM行
-e 逻辑或,匹配多个模式直接的任意一个,grep -e PATERN1 -e PATHERN2 file
-w #匹配整个单词
-E #使用增强正则表达式。 grep -E 等同于 egrep
-F #不支持正则表达式。grep -F 等同于 fgrep

实例

  1. 查找出当前系统中所有网卡的IPv4地址
[centos7@root ~]# ifconfig | egrep -o "\<(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-5])\>"
192.168.17.20
255.255.255.0
192.168.17.255
172.18.17.20
255.255.0.0
172.18.255.255
127.0.0.1
255.0.0.0
192.168.122.1
255.255.255.0
192.168.122.255
  1. 查找出磁盘分区利用率最大的数字
[centos6@root app]# df | egrep "/dev/sda" | tr -s " " "%" | cut -d% -f5 | sort -rn | head -n1
12