文本处理工具 Grep

Posted by Sunday on 2018-02-23

文本搜索工具,根据用户指定的文本模式(搜索条件)对目标文件进行逐行搜索,显示能匹配到的行

grep:最常用,可以检索目标(一个活多个单词或正则表达式)。
egrep:支持丰富的正则表达式,而且支持多目标检索,等同于 grep -e。
fgrep:不能使用正则表达式,可以检索多个目标,等同于 grep -f,不建议使用。

Grep命令选项

1
2
3
4
5
6
7
8
9
10
-v: 反向选取,显示不匹配的行
-i: 忽略字符大小写
-n: 列出检索目标所在的行号
-o: 仅显示匹配的字串,而非字串所在的行
-w: 精确匹配单词所在行 如 -w go 此时只显示go的行,不会显示good.
-l: 列出匹配模式的文件名,而不是打印匹配的行
-E: 支持使用扩展正则表达式
-A #: 包含目标的后几行 例 grep -A3 包含目标的后3行
-B #: 包含目标的前几行 例 grep -B3 包含目标的前几行
-C #: 包含目标的前后几行 例 grep -C3 包含目标的前后各3行

基础正则表达式(BRE)

字符匹配

. : 匹配任意单个字符
[] : 匹配[]范围内的任意单个字符
[^] : 匹配[]范围外的任意单个字符
[-] : 匹配[]中指定范围内的任意一个字符,如[0-9],[a-z],A-Z]

POSIX字符类
[[:digit:]] : 匹配任意一个数字字符
[[:lower:]] : 匹配小写字母
[[:upper:]] : 匹配大写字母
[[:space:]] : 匹配一个包括换行符、回车等在内的所有空白符
[[:punct:]] : 匹配标点符号
[[:alpha:]] : 匹配任意一个字母(包括大小写)
[[:alnum:]] : 匹配任意一个字母或数字字符

次数匹配

* : 匹配其前面的字符任意次(包括0次)例:x*y 如:xxy(x出现2次), xyy(x出现1次),y(x出现0次)
.* : 匹配任意长度的任意字符(工作于贪婪模式:尽可能多的去匹配)
\? : 匹配其前面的字符0次或1次,即前面的字符可有可无 例:x\?y 如:`xy`, `y`, a`y`
\+ : 匹配其前面的字符至少1次;

\{m\} : 匹配前面的字符m次 例: x\{2\}y 如: `xxy`,x`xxy`,xx`xxy`,
\{m,n\} : 匹配其前面的字符至少m次,至多n次 例: x\{2,5\}y 如: xxy,xxxy,xxxxy
\{m,\} : 匹配其前面的字符至少m次
\{0,n\}: 匹配其前面的字符至多n次

位置锚定

^ : 行首锚定;用于模式最左侧
$ : 行尾锚定;用于模式最右侧
^$ : 空白行
^[[:space]] : 空白行
^a# : 模式(a)匹配整行

单词锚定

不包含特殊字符的连续字符组成的串叫单词:
\<或\b : 词首,出现于单词左侧 如\<char
\>或\b : 词尾,出现于单词右侧 如char\>
\<hello\> : 匹配hello整个单词

分组

\(\)
例如:\(ab\)*
分组中的模式匹配到的内容,可由正则表达式引擎记忆在内存中,之后可被 \1, \2, \3引用
\1: 从左侧起,第一个左括号以及与之匹配右括号之间的模式所匹配到的字符;
\2:从左侧起,第二个左括号以及与之匹配右括号之间的模式所匹配到的字符;

引用

有编号:自左而后的左括号,以及与其匹配右括号
\n: 引用第n个括号所匹配到的内容,而非模式本身
\(ab\+\(xy\)*\):
\1: ab\+\(xy\)*
\2: xy

基本正则例题

1、显示/proc/meminfo文件中以大小s开头的行;(要求:使用两种方式)

1
2
3
grep "^[sS]" /proc/meminfo
grep -i "^s" /proc/meminfo
grep -e ^s -e ^S /proc/meminfo

2、显示/etc/passwd文件中不以/bin/bash结尾的行;

1
grep -v "/bin/bash$" /etc/passwd

3、显示/etc/passwd文件中ID号最大的用户的用户名;

1
sort -t: -k 3 /etc/passwd | cut -d: -f 1 | tail -n 1

4、如果用户root存在,显示其默认的shell程序;

1
2
grep -r "^root.*" /etc/passwd | cut -d: -f7
id root &> /dev/null && grep "^root\>" /etc/passwd | cut -d: -f7

5、找出/etc/passwd中的两位或三位数;

1
2
grep --color=auto "\<[0-9]\{2,3\}\>" /etc/passwd
grep --color=auto "\b[0-9]\{2,3\}\b" /etc/passwd

6、找出”netstat -tan”命令的结果中以’LISTEN’后跟0、1或多个空白字符结尾的行;

1
netstat -tan | grep "LISTEN[[:space:]]*$"

7、添加用户bash、testbash、basher以及nologin(其shell为/sbin/nologin);而后找出/etc/passwd文件中用户名同shell名的行;

1
grep "^\([[:alnum:]]\+\>\).*\1$" /etc/passwd

8、显示/etc/passwd文件中其默认shell为/bin/bash的用户;

1
grep "/bin/bash$" /etc/passwd

9、显示/boot/grub2/grub.cfg中以至少一个空白字符开头的行;

1
grep "^[[:space:]]\+[^[:space:]]" /boot/grub2/grub.cfg

10、使用echo命令输出一个绝对路径,使用grep取出其基名;

1
echo "/etc/passwd/" | grep -o "[[:alpha:]]\+" | tail -n 1

扩展正则表达式(ERE)

字符匹配

. : 匹配任意单个字符
[] : 匹配[]范围内的任意单个字符
[^] : 匹配[]范围外的任意单个字符
[-] : 匹配[]中指定范围内的任意一个字符,如[0-9],[a-z],A-Z]

POSIX字符类:
[[:digit:]] : 匹配任意一个数字字符
[[:lower:]] : 匹配小写字母
[[:upper:]] : 匹配大写字母
[[:space:]] : 匹配一个包括换行符、回车等在内的所有空白符
[[:punct:]] : 匹配标点符号
[[:alpha:]] : 匹配任意一个字母(包括大小写)
[[:alnum:]] : 匹配任意一个字母或数字字符        \:转义符,将特殊字符进行转义,忽略其特殊意义

次数匹配

* : 匹配其前面的字符任意次(包括0次)例:x*y 如:xxy(x出现2次), xyy(x出现1次),y(x出现0次)
.* : 匹配任意长度的任意字符(工作于贪婪模式:尽可能多的去匹配)
? : 匹配其前面的字符0次或1次,即前面的字符可有可无 例:x\?y 如:`xy`, `y`, a`y`
+:匹配其前面的字符至少1次;

{m} : 匹配前面的字符m次 例: x\{2\}y 如: `xxy`,x`xxy`,xx`xxy`,
{m,n} : 匹配其前面的字符至少m次,至多n次 例: x\{2,5\}y 如: xxy,xxxy,xxxxy
{m,} : 匹配其前面的字符至少m次
{0,n}: 匹配其前面的字符至多n次

位置锚定

^ : 行首锚定;用于模式最左侧
$ : 行尾锚定;用于模式最右侧
^$ : 空白行
^[[:space]]*$ : 空白行
^a# : 模式(a)匹配整行

单词锚定

不包含特殊字符的连续字符组成的串叫单词:
\<或\b : 词首,出现于单词左侧 如\<char
\>或\b : 词尾,出现于单词右侧 如char\>
\<hello\> : 匹配hello整个单词

分组

()
例如:(ab)*de
分组中的模式匹配到的内容,可由正则表达式引擎记忆在内存中,之后可被 \1, \2, \3引用
\1: 从左侧起,第一个左括号以及与之匹配右括号之间的模式所匹配到的字符;
\2:从左侧起,第二个左括号以及与之匹配右括号之间的模式所匹配到的字符;

后向引用

有编号:自左而后的左括号,以及与其匹配右括号
\n: 引用第n个括号所匹配到的内容,而非模式本身
a|b
A|hello:A或hello

区别

扩展正则表达式与基础正则表达式的唯一区别在于:? + () {} 这几个字符。

基础正则表达式中,如果你想? + () {}表示特殊含义,你需要将他们转义
而扩展正则表达式中,如果你想? + () {} 不表示特殊含义,你需要将他们转义

扩展正则例题

1、显示/proc/meminfo文件中以大小s开头的行;(要求:使用三种方式)

1
2
3
egrep "^[sS]" /proc/meminfo
egrep -i "^s" /proc/meminfo
egrep "^(s|S)" /proc/meminfo

2、显示/etc/passwd文件中不以/bin/bash结尾的行;

1
egrep -v "/bin/bash$" /etc/passwd

3、显示/etc/passwd文件中ID号最大的用户的用户名;

1
sort -t: -k 3 /etc/passwd | cut -d: -f 1 | tail -n 1

4、如果用户root存在,显示其默认的shell程序;

1
2
id root &> /dev/null && egrep "^root\>" /etc/passwd | cut -d: -f7
egrep "^root\b" /etc/passwd | cut -d: -f7

5、找出/etc/passwd中的两位或三位数;

1
egrep "\<[0-9]{2,3}\>" /etc/passwd

6、显示/etc/rc.d/rc.sysinit文件中,至少以一个空白字符开头的且后面存非空白字符的行;

1
egrep "^[[:space:]]+[^[:space:]]" /etc/rc.d/rc.sysinit

7、找出”netstat -tan”命令的结果中以’LISTEN’后跟0、1或多个空白字符结尾的行;

1
netstat -tan | egrep "LISTEN[[:space:]]*$"

8、添加用户bash、testbash、basher以及nologin(其shell为/sbin/nologin);而后找出/etc/passwd文件中用户名同shell名的行;

1
egrep "^([[:alnum:]]+\>).*\1$" /etc/passwd

9、显示/boot/grub/grub.conf中以至少一个空白字符开头的行;

1
egrep "[:space:]+[^[:space:]]" /boot/grub2/grub.cfg

10、显示/boot/grub2/grub.cfg文件中以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;

1
egrep "^#+[[:space:]+[^[:space:]]" /boot/grub2/grub.cfg

11、使用echo命令输出一个绝对路径,使用grep取出其基名;

1
echo "/etc/passwd/" | egrep -o "[[:alpha:]]+" | tail -n 1

12、显示当前系统root、nginx或mysql用户的默认shell和UID;

1
egrep "^(root|nginx|mysql)\>" /etc/passwd | cut -d: -f1,3,7

13、找出/etc/rc.d/init.d/functions文件中某单词后面跟一个小括号的行;

1
egrep -o "^[_[:alpha:]]+\(\)" /etc/rc.d/init.d/functions

http://www.178linux.com/86847