文本处理三剑客简介
- grep:文本过滤工具
grep(基本正则表达式),egrep(扩展正则表达式),fgrep(不知正则表达式搜索) - sed:stream editor,文本编辑工具
- awk:Linux上的实现gawk,文本报告生成器
1、grep
- grep: Global search REgular expression and Print out the line
作用:文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行
模式:由正则表达式字符及文本字符所编写的过滤条件 - 用法:
grep [OPTIONS] PATTERN [FILE...]
grep root /etc/passwd
grep "$USER" /etc/passwd
grep '$USER' /etc/passwd
grep \whoami\
/etc/passwd - 选项:
--color=auto: 对匹配到的文本着色显示
-v: 显示不被pattern匹配到的行,取反
-i: 忽略字符大小写
-n:显示匹配的行号
-c: 统计匹配的行数
-o: 仅显示匹配到的字符串,字符会一个字符占用一行显示,排成一列
-q: 静默模式,不输出任何信息,用于设置密码
-A #: after, 后#行
-B #: before, 前#行
-C #:context, 前后各#行
-e:实现多个选项间的逻辑或关系
如:grep -e test1 -e test2 file 搜索既属于test1用户又属于test2用户的文件
-w:匹配整个单词
-E:使用ERE,相当于扩展正则表达式
-F:相当于fgrep,不支持正则表达式
知识扩展:
查找1到100中包含9的数字
seq 100 |grep 9 |wc -l
2、正则表达式
- REGEXP:由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能
- 程序支持:grep,sed,awk,vim, less,nginx,varnish等
- 分两类:
基本正则表达式:BRE
扩展正则表达式:ERE
grep -E, egrep - 正则表达式引擎:
采用不同算法,检查处理正则表达式的软件模块
PCRE(Perl Compatible Regular Expressions)
*元字符分类:字符匹配、匹配次数、位置锚定、分组 - man 7 regex man帮助第七章节
2.1 基本正则表达式元字符
- 字符匹配
. 匹配任意单个字符
[] 匹配指定范围内的任意单个字符
[^] 匹配指定范围外的任意单个字符
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母 [:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字 [:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号 - 匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数
匹配前面的字符任意次,包括0次
贪婪模式:尽可能长的匹配
. 任意长度的任意字符
\? 匹配其前面的字符0或1次
+ 匹配其前面的字符至少1次
{n} 匹配前面的字符n次
{m,n} 匹配前面的字符至少m次,至多n次
{,n} 匹配前面的字符至多n次
{n,} 匹配前面的字符至少n次 - 位置锚定
^ 行首锚定,用于模式的最左侧
$ 行尾锚定,用于模式的最右侧
^PATTERN$ 用于模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行
\< 或 \b 词首锚定,用于单词模式的左侧
> 或 \b 词尾锚定;用于单词模式的右侧
\<PATTERN> 匹配整个单词
练习:
1、获取分区利用率,并从大到小排序
df |grep "^/dev/sd" |tr -s " " % |cut -d% -f5 |sort -nr
或df |grep "dev/sd"|egrep -o "[0-9]{1,3}%"|egrep -o "[0-9]{1,3}" |sort -nr
2、统计/etc目录下所有以.conf结尾的文件的个数
ls -R /etc |grep "\.conf$"|wc -l
3、统计.rpm前的类似x86_64出现多少次
ls /misc/cd/Packages/*.rpm |rev |cut -d. -f2 |rev|sort|uniq -c
或ls /misc/cd/Packages/ |grep -o "[^.]\+\.rpm"|cut -d. -f1|sort|uniq -c
- 分组::() 将一个或多个字符捆绑在一起,当作一个整体进行处理,如:(root)+
- 分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为: \1, \2, \3, ...
- \1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
示例: (string1+(string2)*)
\1 :string1+(string2)*
\2 :string2 - 后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身
- 或者:|
示例1:
a\|b: a或b
C\|cat: C或cat
\(C\|c\)at:Cat或cat
示例2:
(1)root后面又出现root
echo rootxxxxroot |grep "\(root\).*\1"
结果为:rootxxxxroot
(2)root和wang在后面分别又出现,root和wang之间有其他字符
echo root233wangxxxxrootxxxwang |grep "\(root\).*\(wang\).*\1.*\2"
结果为:root233wangxxxxrootxxxwang
示例:在/etc/passwd文件中,前面出现root,后面又出现root的行,root不一定在行首
grep "\(\<root\>\).*\1" /etc/passwd 使用首尾锚定
结果显示为:root:x:0:0:root:/root:/bin/bash
注意:\1匹配的结果是前面的模式匹配的结果,而不是模式本身
示例:
[root@centos7 ~]#echo "aa roo xx ryy" |grep "\<\(r..\).*\1"
[root@centos7 ~]#
模式“\<\(r..\)”匹配的结果是roo,那么后面\1匹配的必须是roo,ryy不符合该结果
练习:
1、显示/proc/meminfo文件中以大小s开头的行(要求:使用两种方法)
grep -e "^s" -e "^S" /proc/meminfo
或grep -i "^s" /proc/meminfo
2、显示/etc/passwd文件中不以/bin/bash结尾的行
grep -v "/bin/bash$" /etc/passwd
3、显示用户rpc默认的shell程序
cat /etc/passwd |grep "^rpc\>" |cut -d: -f7
4、找出/etc/passwd中的两位或三位数
grep -o "\<[0-9]\{2,3\}\>" /etc/passwd
5、显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面有非空白字符的行
grep "^[[:space:]]\+\.*[^[:space:]]\+" /etc/grub2.cfg
6、找出“netstat -tan”命令结果中以LISTEN后跟任意多个空白字符结尾的行
netstat -tan |grep "\<LISTEN\>[[:space:]]\+"
7、显示CentOS7上所有系统用户的用户名和UID
cat /etc/passwd |cut -d: -f1,3
8、利用df和grep,取出磁盘各分区利用率,并从大到小排序
df |grep "/dev/sd"|grep -o "[0-9]\{1,3\}%"|grep -o "[0-9]\{1,3\}"|sort -nr
egrep及扩展的正则表达式
- egrep=grep -E
- egrep [OPTIONS] PATTERN [FILE...]
- 扩展正则表达式的元字符:
- 字符匹配:
. 任意单个字符
[] 指定范围的字符
[^] 不在指定范围的字符
3、扩展正则表达式
- 次数匹配:
*:匹配前面字符任意次
?: 0或1次
+:1次或多次
{m}:匹配m次
{m,n}:至少m,至多n次 - 位置锚定:
^ :行首
$ :行尾
\<, \b :语首
>, \b :语尾 - 分组:
()
后向引用:\1,\2,... - 或者:
a|b: a或b
C|cat: C或cat
(C|c)at:Cat或cat
练习:
1、显示三个用户root、mage、wang的UID和默认shell
grep -E "(root|test1|yuan)" /etc/passwd |cut -d: -f3,7
2、找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行
grep "^.*\>[^[:space:]]*()" /etc/rc.d/init.d/functions
3、使用egrep取出/etc/rc.d/init.d/functions中其基名
echo /etc/rc.d/init.d/functions |egrep -o "[^/]+$"
4、使用egrep取出上面路径的目录名
echo /etc/rc.d/init.d/functions |egrep -o "^.*/"
5、统计last命令中以root登录的每个主机IP地址登录次数
last |grep -w "root" |egrep -o "([0-9]{1,3}\.){3}[1-9]{1,3}"|sort|uniq -c|sort -nr
6、利用扩展正则表达式分别表示0-9、10-99、100-199、200-249、250-255
ifconfig |egrep -o "(([0-9][1-9]?|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9][1-9]?|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
7、显示ifconfig命令结果中所有IPv4地址
ifconfig|egrep -o "([0-9]{1,3}\.){3}[1-9]{1,3}"
8、将此字符串:welcome to magedu linux 中的每个字符去重并排序,重复次数多的排到前面
echo "welcome to magedu linux" |grep -o "[[:alpha:]]" |sort|uniq -c|sort -nr
知识扩展:
获取IP地址:
1、使用cut命令:
centos7版本:
ifconfig ens33 | head -n2 |tail -n1|tr -s " " |cut -d " " -f3
centos6版本:
ifconfig eth0 | head -n2 |tail -n1 |tr -s " " : |cut -d : -f4
2、使用grep命令:
ifconfig ens33 |grep -w "inet"|tr -s " " :|cut -d: -f3
3、使用正则表达式(字符匹配):
ifconfig ens33 |grep -o '[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}\.[[:digit:]]\{1,3\}'
以一个ip地址中的一位作为一个整体(如192. ,是三位加上.)
4、使用正则表达式(匹配次数):
方法1:ifconfig ens33 |grep -w "inet" |grep -o "[0-9.]\{7,\}" |head -n1 以一个ip地址作为一个整体(如1.1.1.1,是7位字符)
方法2:ifconfig ens33 |grep -o "inet [0-9.]\+"|cut -d" " -f2
5、使用正则表达式(分组):
ifconfig ens33 |grep -w "inet" |grep -o "\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}"|head -n1
6、使用扩展正则表达式:
ifconfig ens33 |grep -w "inet" |grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}"|head -n1
获取版本号:
cat /etc/centos-release |tr -dc '[:digit:].' | cut -d. -f1
或cat /etc/redhat-release |tr -dc '[:digit:].' | cut -d. -f1
文章评论