个人博客地址:http://www.pojun.tech/ 欢迎访问
前言
在Linux的使用过程中,需要处理大量的文本文件,这很符合Linux的哲学思想——一切皆文件。也是因为如此,我们在使用Linux的过程中就需要进行各种各样的文本处理,而在Linux中最著名也最试用的就是文本处理三剑客,他们分别是grep、sed、awk。而三剑客在使用的过程中又有不同的侧重,例如grep是文本过滤工具,sed是文本编辑工具,awk是文本报告生成器。今天将主要介绍的是文本过滤工具grep。
本文将通过以下几个方面的内容来介绍grep的使用。
1.grep命令的使用
2.基本正则表达式
3.基本正则表达式练习
4.扩展正则表达式
5.扩展正则表达式练习
grep命令的使用
grep 全称为 Global search REgular expression and Print outthe line
作用是文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行
这里的模式是指:由正则表达式字符及文本字符所编写的过滤条件
使用方式:grep [OPTIONS] PATTEN [FILE]
grep root /etc/passwd
grep "$USER" /etc/passwd
grep '$USER' /etc/passwd
grep `whoami` /etc/passwd
由上面的案例可以看出grep可以匹配 变量和某些简单的命令,但是一般而言还是配合正则表达式来使用。
选项
--color=auto: 对匹配到的文本着色显示
-v: 显示不被pattern匹配到的行
-i: 忽略字符大小写
-n:显示匹配的行号
-c: 统计匹配的行数
-o: 仅显示匹配到的字符串
-q: 静默模式,不输出任何信息
-A #: after, 后#行
-B #: before, 前#行
-C #:context, 前后各#行
-e:实现多个选项间的逻辑or关系 grep –e ‘cat ’ -e ‘dog’ file
-w:匹配整个单词
-E:使用ERE
-F:相当于fgrep,不支持正则表达式
基本正则表达式
REGEXP:由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能。
正则表达式是描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串,将匹配的某种子串替换,或者从某个串中取出符合某个条件的子串。
在Linux中有很多软件都支持正则表达式,例如grep,sed,awk,vim,less,nginx,varnish。
当然在很多的编程语言中也是支持正则表达式的,例如Java,Python,JavaScript等等。从这一点上可以看出,正则表达式的应用其实是IT领域的一项基本应用。
在Linux中正则表达式分为两种,分别是基本正则表达式,和扩展正则表达式,我们将一个一个地来介绍。
正则表达式分为以下几类:字符匹配、匹配次数、位置锚定、分组
基本正则表达式 字符匹配
元字符 | 定义 |
---|---|
. | 任意单一字符 |
[ ] | [ ]内任意单一字符 |
[^] | 除[ ]内任意单一字符 |
[:alnum:] | 字母和数字 |
[:alpha:] | 代表任何英文大小写字符,亦即 A-Z, a-z |
[:lower:] | 小写字母 |
[:upper:] | 大写字母 |
[:blank:] | 水平空白字符(空格和制表符) |
[:space:] | 所有水平和垂直的空白字符(比[:blank:]包含的范围广) |
[:cntrl:] | 不可打印的控制字符(退格、删除、警铃...) |
[:digit:] | 十进制数字 |
[:graph:] | 可打印的非空白字符 |
[:print:] | 可打印字符 |
[:punct:] | 标点符号 |
[:xdigit:] | 十六进制数字 |
基本正则表达式 匹配次数
用在要指定次数的字符后面,用于指定前面的字符要出现的次数
元字符 | 定义 |
---|---|
* | * 匹配前面的字符任意次,包括0次。贪婪模式:尽可能长的匹配 |
.* | 任意长度字符 |
\+ | \+ 前面字符至少1次 |
\? | ?前面字符重复0或1次 |
\{n\} | 前面字符重复n次 |
\{n,\} | 匹配前面地字符至少n次 |
\{,n\} | 匹配前面地字符至多n次 |
\{m,n\} | 匹配前面地字符至少m次至多n次 |
基本正则表达式 位置锚定
用来指定某个字符出现地位置
元字符 | 定义 |
---|---|
^ | 行首锚定,用于模式的最左侧 |
$ | 行尾锚定,用于模式的最右侧**** |
^PATTERN$ | 用于模式匹配整行 |
^$ | 空行 |
^[[:space:]]*$ | 空白行 |
\< | 词首锚定,用于单词模式的左侧 |
\> | 词尾锚定;用于单词模式的右侧 |
基本正则表达式 分组
可以将分组理解为正则表达式地 复用。同一种匹配格式不用重复去写,例如IP。
分组:() 将一个或多个字符捆绑在一起,当作一个整体进行处理,如:(root)+
分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, …
\1 表示从左侧起第一个左括号以及与之匹配右括号之间的 模式所匹配到的字符
示例: (string1+(string2)*)
\1 :string1+(string2)*
\2 :string2
后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身
或者:|
示例:a|b: a或b C|cat: C或cat (C|c)at:Cat或cat
基本正则表达式练习
-
显示/proc/meminfo文件中以大小s开头的行(要求:使用两种方法)
grep -i "^s" /proc/meminfo grep "^[sS]" /proc/meminfo
-
显示/etc/passwd文件中不以/bin/bash结尾的行
grep -v "/bin/bash$" /etc/passwd
-
显示用户rpc默认的shell程序
grep "^rpc\>" /etc/passwd |cut -d: -f7 grep -w "^rpc" /etc/passwd |cut -d: -f7
-
找出/etc/passwd中的两位或三位数
grep -o "\<[[:digit:]]\{2,3\}\>" /etc/passwd
-
显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面存非空白字符的行
grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg
-
找出“netstat -tan”命令的结果中以‘LISTEN’后跟任意多个空白字符结尾的行
netstat -tan | grep "LISTEN[[:space:]]*$"
-
显示CentOS7上所有系统用户的用户名和UID
cut -d: -f1,3 /etc/passwd | grep "\<[[:digit:]]\{,3\}$"
-
添加用户bash、testbash、basher、sh、nologin(其shell为/sbin/nologin),找出/etc/passwd用户名同shell名的行
grep "^\([[:alnum:]]\+\)\>.*/\1$" /etc/passwd
-
利用df和grep,取出磁盘各分区利用率,并从大到小排序
df |grep "^/dev/sd" | grep -o "\<[[:digit:]]\+%" |sort -nr|tr -d "%"
扩展正则表达式
扩展的正则表达式是grep命令加上 -E 选项,才能够支持的,也就是egrep。
其余选项与 grep 一致。
扩展的正则表达式基本元字符
元字符 | 定义 |
---|---|
. | 任意单个字符 |
[ ] | 指定范围的字符 |
[^] | 不在指定范围的字符 |
* | 匹配前面字符任意次 |
? | 0或1次 |
+ | 1次或多次 |
{m} | 匹配m次 |
{m,n} | 至少m,至多n次 |
^ | 行首 |
$ | 行尾 |
\< | 语首 |
\> | 语尾 |
( ) | 后向引用:\1,\2... |
| | 或者 |
扩展的正则表达式练习
-
显示三个用户root、mage、wang的UID和默认shell
egrep "^(root|mage|wang)\>" /etc/passwd|cut -d : -f3,7
-
找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行
egrep "^[[:alnum:]_]+\(\)" /etc/rc.d/init.d/functions
-
使用egrep取出/etc/rc.d/init.d/functions中其基名
echo /etc/rc.d/init.d|egrep -o "[^/]+/?$"
-
使用egrep取出上面路径的目录名
echo /etc/rc.d/init.d |egrep -o "^/.*/\<"
-
统计last命令中以root登录的每个主机IP地址登录次数
last|grep "^root\>" |grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}"
-
利用扩展正则表达式分别表示0-9、10-99、100-199、200-249、250-255
"[0-9]" "[1-9][0-9]" "1[0-9]{2}" "2[0-4][0-9]" "25[0-5]"
-
显示ifconfig命令结果中所有IPv4地址
ifconfig | egrep -o "\<(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\>"
-
将此字符串:welcome to magedu linux 中的每个字符去重并排序,重复次数多的排到前面
echo "welcome to magedu linux" |grep -o "." | sort | uniq -c | sort -n