grep命令主要用于在指定文本中根据正则表达式去匹配从而筛选出需要的信息。
首先介绍一下grep命令的常用选项:
-E 支持扩展的正则表达式
-P 支持perl正则表达式
-o 只显示匹配到的内容
-v 显示不匹配的内容
-i 忽略大小写
-A N 显示匹配到的内容所在行的后N行
-B N 显示匹配到的内容所在行的前N行
-C N 显示匹配到的内容所在行的前后N行
其次介绍一些常用的正则表达式(regular expression):
. 匹配任意字符
* 匹配其前面的字符任意次,与通配符的含义不同!
.*组合就是任意个任意字符,相当于通配符中的*
[ ] 匹配其内的字符一次
[^ ] 匹配 除了里面的字符一次
^ 以什么字符开头
$ 以什么字符结尾
< 单词以什么字符开头
> 单词以什么字符结尾
<和>可以统一以表示
分组及后向引用:可以用()将某部分字符括起来,后面用1...来引用,看后面例子有助理解
另:[[:digit:]]表示数字,[[:space:]]表示空格,[[:alpha:]]表示所有英文字母,[[:upper:]]表示大写字母,[[:lower:]]表示所有小写字母
扩展的正则表达式(使用-E选项来支持扩展的正则):
? 匹配其前面的字符0次或1次
{n,m} 匹配其前面的字符n到m次
+ 匹配其前面的字符至少一次
PERl的正则:
w 英文字符(包括字母,数字,下划线)
W 与w相反,非英文字符(包括字母,数字,下划线)
s 空格(包括 , , ,f在内的转义字符)
S 非空格,与s相反
d 数字
D 非数字
还有一种零宽断言的方法来对匹配的内容进行一定的限定,本身并不占用匹配的位置,只做一种限制:
(?=exp) : 限定匹配到的内容其后面必须是exp
(?<=exp) : 限定匹配到的内容其前面面必须是exp
(?!exp) : 限定匹配到的内容其后面必须不是exp
(?<!exp) : 限定匹配到的内容其前面必须不是exp
注:正则表达式工作在贪婪模式下,即尽可能的匹配最长的符合正则的内容
接下来是一些例子(有些-E选项可能并不需要加,但加了又不吃亏):
1.找出/proc/meminfo文件中,所有以大小或小写s开头的行,至少三种方式
grep -i '^s' /proc/meminfo
grep -E '^[sS]' /proc/meminfo
grep -E '^(s|S)' /proc/meminfo
2. 显示当前系统上root,centos或者user1用户的相关信息
grep -E '^(root|user1|centos)>' /etc/passwd
3. 使用echo命令输出一绝对路径,使用grep取出其基名(basename)
echo "/etc/xxx/hhhh" | grep -Eo '[^/]+$'
4.使用echo命令输出一绝对路径,取出其路径名,类似dirname命令的结果
echo "/etc/xxx/hhhh/hhhhh" |grep -E '^/.*/'
5.找出ifconfig命令结果中1-255之间的数值
ifconfig|grep -E '([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
6.找出/etc/passwd文件中用户名跟shell名相同的行
grep -E '^(.*):.*1$' /etc/passwd (此处即用到了分组的后向引用,1所指的内容即为前面第一个括号括起来的正则所匹配到的内容)
7.获取ifconfig中命令的ip地址,使用三种方式实现
ifconfig | grep -Eo 'inet (addr:)?([0-9]+.){3}[0-9]*'|grep -Eo '([0-9]*.){3}[0-9]*'|grep -v '127.0.0.1'
ifconfig | grep -Po '(?<=addr:'')(?!127)([0-9]+.){3}[0-9]+'
ifconfig | grep -Po '(?<=addr:).*(?= B)'