day13 grep命令

day13 grep命令

linux三剑客之grep命令

介绍

grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

grep命令的作用和使用场景

grep命令一般用来筛选数据,一般用来筛选我们需要的数据。		
    格式:
        grep [参数] [过滤的规则] [路径]
        
        标准输出 | grep [参数] [过滤规则]

grep命令的参数

参数:
        -n : 显示过滤出来的文件在文件当中的行号
        -o : 只显示匹配到的内容
        -q : 静默输出(一般用来shell脚本当中)
        -i : 忽略大小写
        -c : 显示匹配到的行数
        -v :反向查找
        -w : 匹配某个词
        -E :使用扩展正则
        -R :递归查询
        -l : 只打印文件路径


扩展参数:
        -A :显示匹配到的数据的后几n行
        -B :显示匹配到的数据的前几n行
        -C :显示匹配到的数据的前后各几n行

知识储备:
        $?	: 代表上一条命令执行是否成功(0:成功,非0代表失败)
        词  :一连串字母和数字组成的字符串
        +   :前导字符的一个或多个
        wc -l : 打印显示有多行

案例

案例1:要求过滤出/etc/passwd中包含的root的行及其行号
    [root@localhost ~]# grep -n "root" /etc/passwd			# 用-n参数打印包含的root的行及其行号
    1:root:x:0:0:root:/root:/bin/bash
    10:operator:x:11:0:operator:/root:/sbin/nologin
    
案例2:要求过滤出/etc/passwd中包含的root的行,只显示过滤到的内容
    [root@localhost ~]# grep -n -o "root" /etc/passwd		 # 只显示过滤到的内容
    
案例3:要求过滤/etc/passwd中的Root,静默输出
    [root@localhost ~]# grep -o -q "root" /etc/passwd         # 静默输出,要和 $? 配合使用
    [root@localhost ~]# echo $?      # $?	: 代表上一条命令执行是否成功(0:成功,非0代表失败)
    0     # 0代表成功

案例4:要求过滤/etc/passwd中的Root,忽略大小写
	[root@localhost ~]# grep -i "ROOT" /etc/passwd    		# -i参数:忽略大小写
    
案例5:要求匹配mail及其后两行
	[root@localhost ~]# grep -n -A 2 "mail" /etc/passwd     # -A参数:会匹配mail及其后两行

案例6:要求匹配mail及其前两行
	[root@localhost ~]# grep -n -B 2 "mail" /etc/passwd     # -B参数:会匹配mail及其前两行
	
案例7:要求匹配mail及其前后各两行
	[root@localhost ~]# grep -C 2 "mail" /etc/passwd        # -C参数:会匹配mail及其前后各两行
	
案例8:要求显示包含root的行有多少行
    [root@localhost ~]# grep -c "root" /etc/passwd           # -c参数:会显示匹配到的行数
    2
    
案例9:要求查询不包含root的行
    [root@localhost ~]# grep -v "root" /etc/passwd           # -v参数:反向查找

案例10:匹配meng这个词
	[root@localhost ~]# grep -w "meng" 1.txt                 # -w参数:匹配meng个词
	
案例11:要求匹配出包含meng的行
    [root@localhost ~]# grep -E "(meng)+" 1.txt              # 扩展正则需要加上 -E
    meng
    meng:zhang
    
案例12:要求找出/etc目录下,那些文件中包含root
	[root@localhost ~]# grep -R "root" /etc		         # -R :递归查询 
    [root@localhost ~]# grep -Rl "root" /etc              # -R :递归查询  l : 只打印文件路径
    
案例13:计算/etc目录下包含root的文件有多少个?
	[root@localhost ~]# grep -Rl "root" /etc/ | wc -l    # wc-l:打印显示有多行
	145
	
案例14:查询/etc/passwd文件中包含/bin/bash的行并输出行号
	[root@localhost ~]# grep -n "/bin/bash" /etc/passwd  # 显示行号

案例15:过滤出当前主机包含的IP
    192.168.15.50
    [root@localhost ~]# ip a | grep -o -E "([0-9]{1,3}\.){3}[0-9]{1,3}"
    ip a	:查看ip命令
    grep -o -E  :扩展正则
    ([0-9]{1,3}\.) :前面0-9匹配三次
    \.      :转意,只是单纯一个点号

正则表达式

一、什么是正则表达式
    1、正则表达式就是为了处理大量的文本|字符串而定义的一套规则和方法
    2、通过定义的这些特殊符号的辅助,系统管理员就可以快速过滤,替换或输出需要的字符串。Linux正则表达式一般以行为单位处理。
    简单说:
        为处理大量文本|字符串而定义的一套规则和方法
        以行为单位出来,一次处理一行
    3、正则表达式是一种描述一组字符串的模式,类似数字表达式,通过各种操作符组成更小的表达式
    
二、为何使用正则表达式
    1、linux运维工作,大量过滤日志工作,化繁为简。
    2、简单,高效。
    3、正则表达式高级工具;三剑客都支持
    
三、正则表达式的分类
    1、普通正则表达式
    2、扩展正则表达式
    
四、应用场景
	正则表达式是通过包含特殊含义的一些字符去适配各种匹配场景,从而匹配出我们想要的结果
    例如:
        1、怎样验证用户输入的手机号?

        2、怎样验证用户输入的邮箱?

        3、怎样验证用户输入的身份证号码?

普通正则表达式

*			:匹配零个或多个前导字符
$ 			:以前导字符结尾
.			:匹配任意一个字符(换行符除外)
^			:以前导字符开头的行
[^]			:取反
.*			:所有的字符的任何个数
[]			: 或者(其中包含的所有的字符的或者)eth[01]
[a-z]		:a-z所有的一个字母
[A-Z]		:A-Z所有的一个字母
[0-9]		:0-9所有的一个数字
词

案例1:匹配包含22的行
    [root@localhost ~]# grep "22*" 1.txt    # 先找到第1个2,
    2222
    333322222
	22*   # 第一个2是匹配333322222中第一个2,2*是匹配后面所有的2

案例2:以3结尾的行
	[root@localhost ~]# grep "33$" 1.txt   # 33$ :  3是匹配条件,3$是$的前导字符,必须是以3结尾的
    112333
    222333
    4453333
    
案例3:要求输出包含eth的行
    [root@localhost ~]# grep "eth." 2.txt   # .匹配任意一个字符,和eth?占位符差不多
    
案例4:过滤1开头的
    [root@localhost ~]# cat 1.txt
    112333
    222333
    s3
    [root@localhost ~]# grep "^1" 1.txt    # 查询到以1开头的行
    112333
    
案例5:要求打印出/etc/nginx/nginx.conf中的不是以#开头的行
	[root@localhost ~]# grep "^[^#]" /etc/nginx/nginx.conf
	
案例6:要求匹配出2后面有任意数量的任意字符 
    [root@localhost ~]# grep "2.*" 1.txt    # 至少要包含一个2,有一个2,2后面的都会匹配上
    112333
    222333
    
案例7:要求匹配出本机中所有的普通用户
    [root@localhost ~]# grep ":[0-9][0-9][0-9][0-9]" /etc/passwd
    test01:x:1000:1000::/home/test01:/bin/bash    # 大于1000为普通用户

扩展正则表达式

扩展正则表达式(grep 必须加-E参数,或者使用egrep命令)

    egrep  等价于  grep -E 
 
    +			: 前导字符的一个或多个
    ?			: 前导字符的零个或一个
    |			:  或者(竖线两边的字符的或者)
    ()			: 分组,组成一个整体	
    \n      :  n代表的是前面第几个分组 \1\2
    {m,n}		:  范围,至少有m个,最多有n个
    {m}		:  范围,固定m个
    {m,}	: 范围,至少有m个
    
案例1:匹配一个或多个2
	[root@localhost ~]# grep -E "2+" 1.txt    # 至少有一个2
    2
    112333
    222333
    22223333455
    333444222
    12312
    [root@localhost ~]# grep -E "22+" 1.txt  # 至少有两个2
    222333
    22223333455
    333444222
    [root@localhost ~]# grep "22*" 1.txt    # 至少有一个2
    [root@localhost ~]# grep -E "2{1,}" 1.txt  # 至少有一个2
    
案例2:查询出3个2
    [root@localhost ~]# grep -E "2{3}" 1.txt   # 范围查询
    222333
    22223333455
    333444222
    
案例3:查询出包含 22 或者 33 的行
    [root@localhost ~]# grep -E "22|33" 1.txt   # 22和33是两个条件,哪个符合都可以
    112333      # 获取33
    222333
    22223333455
    333444222

案例4:匹配出包含12341234的行
    [root@localhost ~]# grep -E "(1234){2}" 1.txt
    123412341234
    [root@localhost ~]# grep -E "(1234)\1" 1.txt     \1:代表第一个分组

案例5;要求匹配出包含1234abcd1234abcd的行
    root@localhost ~]# grep -E "(1234)(abcd)\1\2" 1.txt
    1234abcd1234abcd

应用场景解答

1、过滤出当前系统IP
    [root@localhost ~]# ip a | grep -o -E "([0-9]{1,3}\.){3}[0-9]{1,3}"
    127.0.0.1
    192.168.15.200
    192.168.15.255
    172.16.1.200
    172.16.15.255

    192.            :([0-9]{1,3}\.)
    192.168.15.     :{3}
    200             :[0-9]{1,3}
    
2、过滤出手机号
    [root@localhost ~]# echo 15124945555 | grep -E "(151|176|187|136|166|177|138|)[0-9]{8}"
    15124945555
    
3、过滤出邮箱
    [root@localhost ~]# echo "12345@qq.com" | grep -E "[0-9a-zA-Z]+@[0-9a-z]+(\.com|\.con\.cn|\.edu|\.edu\.cn)"
    12345@qq.com	
上一篇:openpyxl读写操作


下一篇:day13