Linux文本处理命令grep及正则表达式

一、grep

1、grep概述

(1)作用:grep是一文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行

(2)模式:由正则表达式字符及文本字符所编写的过滤条件

2、命令格式

    grep [选项] 模式 [文件…]

    案例:打印passwd文件中root用户的信息

[root@localhost ~]# grep root /etc/passwd
root:x:0:0:root,mgedu,123456,23456:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

3、grep选项

选项

功能

--color=auto

对匹配到的文本着色显示

-v

显示不被pattern匹配到的行

-i

忽略字符大小写

-n

显示匹配的行号,此处的行号时该内容在原文件中的行号

-c

统计匹配的行数

-o

仅显示匹配到的字符串

-q

静默模式,不输出任何信息

-A

输出满足条件的前几行,比如grep –B 3 “aa” file表示在file中输出有aa的行,同时还要输出aa的前三行

-B

输出满足条件的后几行

-C #

相当于同时用-A –B,即前后都输出

-e

实现多个选项间的逻辑or关系grep e cat -e dog file

-w

匹配整个单词

-E

相当于egrep 支持扩展的正则表达式

-F

相当于fgrep,不支持正则表达式

二、正则表达式

1、正则表达式及概述

(1)概述:由一类特殊字符及文本字符所编写的模式,用来在文件中匹配符合条件的字符串,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能。

(2)正则表达式Linux中支持的程序

    grep,sed,awk,vim, less,nginx,varnish

2、基本的正则表达式

(1)字符匹配:

字符

功能

字符

功能

.

匹配任意单个字符

[]

匹配指定范围内的任意单个字符

[^]

匹配指定范围外的任意单个字符

[:alpha:]

代表任何英文大小写字符,亦即 A-Z, a-z

[:alnum:]

字母和数字

[:alpha:]

代表任何英文大小写字符,亦即 A-Z, a-z

[:lower:]

小写字母  

[:upper:]

大写字母

[:blank:]

空白字符(空格和制表符)

[:space:]

水平和垂直的空白字符

[:cntrl:]

不可打印的控制字符(退格、删除、警铃...)

[:digit:]

十进制数字 [:xdigit:]十六进制数字

[:graph:]

可打印的非空白字符

[:print:]

可打印字符

[:punct:]

标点符号



(2)匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数

符号

功能

*

匹配前面的字符任意次,包括0次贪婪模式:尽可能长的匹配

.*

任意长度的任意字符

\?

匹配其前面的字符0或1次

\+

匹配其前面的字符至少1次

\{n\}

匹配前面的字符n次

\{m,n\}

匹配前面的字符至少m次,至多n次

\{,n\}

匹配前面的字符至多n次

\{n,\}

匹配前面的字符至少n次

(3)位置锚定:定位出现的位置

符号

功能

^

行首锚定,用于模式的最左侧

$

行尾锚定,用于模式的最右侧

^PATTERN$

用于模式匹配整行

^$

空行

^[[:space:]]*$

空白行

\< 或 \b

词首锚定,用于单词模式的左侧

\> 或 \b

词尾锚定;用于单词模式的右侧

\<PATTERN\>

匹配整个单词

(4)分组:将一个或多个字符捆绑在一起,当作一个整体进行处理分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3,

\1 :表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

示例:\(string1\+\(string2\)*\)

\1 :string1\+(string2\)*

\2 :string2

后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身

三、正则表达式及grep的使用案例

1、显示/proc/meminfo文件中以大小s开头的行

root@localhost ~]# grep "^[sS]" /proc/meminfo
SwapCached:            0 kB
SwapTotal:       2097148 kB
SwapFree:        2097148 kB
Shmem:              6880 kB
Slab:              82968 kB
SReclaimable:      43660 kB
SUnreclaim:        39308 kB

   还可用如下方式实现:

grep “^s\|^S” /proc/meminfo

grep –i “^s”  /proc/meminfo

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

[root@localhost ~]# grep -v "/bin/bash" /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
……

3、显示用户lp默认的shell程序

[root@localhost ~]# cat /etc/passwd | grep "\blp\b" | cut -d":" -f7
/sbin/nologin

或者cat /etc/passwd | grep "\<lp\>" | cut -d":" -f7

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

[root@localhost ~]#  cat /etc/passwd | grep -o "\b[0-9]\{2,3\}\b"
12
11
12
100
14
50
99
……

或者:cat /etc/passwd | grep -o "\<[0-9]\{2,3\}\>"

5、显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面存非空白字符的行

[root@localhost ~]# cat /etc/grub2.cfg  | grep "^[[:space:]]\+[^[:space:]]\+"
  load_env
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
   set default="${saved_entry}"
  menuentry_id_option="--id"
  menuentry_id_option=""
……

6、找出“netstat -tan”命令的结果中以‘LISTEN’后跟任意多个空白字符结尾的行

[root@localhost ~]# netstat -tan | grep "LISTEN[[:space:]]*$"
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN    
tcp6       0      0 :::22                   :::*                    LISTEN

7、显示CentOS7上所有系统用户的用户名和UID

[root@localhost ~]# cat /etc/passwd | grep -v "root" | grep "\<[0-9]\{1,3\}\>" | cut -d":" -f1,3
bin:1
daemon:2
adm:3
lp:4
sync:5
shutdown:6
halt:7
mail:8
……

8、找出/etc/passwd用户名同shell名的行

[root@localhost ~]# grep "^\<\(.*\)\>.*\b\1\b$" /etc/passwd     
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
[root@localhost ~]# cat /etc/passwd | grep "^\(\b[[:alnum:]]\+\b\):.*\b\1\b$"
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt

9、利用df和grep,取出磁盘各分区利用率,并从大到小排序

[root@localhost ~]# df -h | grep -o "[[:digit:]]\{1,2\}%" | cut -d"%" -f1 | sort -rn
24
7
2

或者:df -h | grep -o "[[:digit:]]\+%"  | tr -d "%" | sort –nr

四、egrep及扩展正则表达式及使用案例

1、egrep的正则表达式及元字符

元字符

功能

元字符

功能

^

行首定位符

$

行尾定位符

.

匹配出换行外的单个字符

*

匹配0个或多个前导字符

[]

匹配指定字符组内任一字符

[^]

匹配不在组内任一字符

+

匹配一次或多次

匹配0此或1次

a|b

匹配a或者b

{m}

匹配m次

{m,n}

至少m,至多n次

\<, \b

语首

\>, \b

语尾

()

分组

2、egrep使用案例

(1)显示三个用户root、mage、wang的UID和默认shell

[root@localhost ~]# egrep "^(\broot\b|\bmage\b|\bwang\b)" /etc/passwd | cut -d":" -f3,7
0:/bin/bash
1008:/bin/bash
1009:/bin/bash

(2)找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行

[root@localhost ~]# cat /etc/rc.d/init.d/functions | egrep "^[_[:alpha:]]+\(\)"
checkpid() {
__pids_var_run() {
__pids_pidof() {
daemon() {
killproc() {
pidfileofproc() {
pidofproc() {
status() {
echo_success() {
echo_failure() {
……

(3)使用egrep取出/etc/rc.d/init.d/functions中其基名

[root@localhost ~]# echo "/etc/rc.d/init.d/functions" | egrep -o "/[[:alpha:]]+$" | egrep -o "[[:alpha:]]+"
functions

(4)使用egrep取出/etc/rc.d/init.d/functions的目录名

[root@localhost ~]# echo "/etc/rc.d/init.d/functions" | egrep -o "/.*/"
/etc/rc.d/init.d/
[root@localhost ~]# echo "/etc/rc.d/init.d/functions" | egrep  -o "/[[:alpha:]]+/(.*/){2}"
/etc/rc.d/init.d/

(5)显示ifconfig命令结果中所有IPv4地址

[root@localhost ~]# ifconfig | egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}"
172.16.250.102
255.255.0.0
172.16.255.255
127.0.0.1
255.0.0.0

(6)将此字符串:welcome to magedu linux 中的每个字符去重并排序,重复次数多的排到前面

[root@localhost ~]# echo "welcome to  magedu linux" | grep -o "[[:alpha:]]" | sort | uniq -c |sort -rn  
      3 e
      2 u
      2 o
      2 m
……