awk,sed,grep运用正则与扩展正则

1.正则与扩展正则的概述 

 

 

 

2.示例 

grep 过滤工具
---格式:grep 【选项】 “正则表达式“ 文件
egrep 过滤工具
---格式:egrep 【选项】 “扩展正则表达式“ 文件
head -5 /etc/passwd > user      //准备素材
grep ^root user    //找以root开头的行
grep bash$ user     //找以bash结尾的行
grep ^$ user   //找空行
grep -v ^$ user  //显示除了空行的内容

grep "[root]" user    //找rot任意一个字符 
grep "[rot]" user    //效果同上
grep "[^rot]" user   //显示r或o或t以外的内容
grep "[0123456789]" user   //找所有数字
grep "[0-9]" user    //效果同上
grep "[^0-9]" user   //显示数字以外内容
grep "[a-z]" user    //找所有小写字母
grep "[A-Z]" user    //找所有大写字母
grep "[a-Z]" user    //找所有字母
grep "[a-Z0-9]" user   //找所有字母和数字
grep "[^a-Z0-9]" user	 //找特殊符号

grep "." user   //找任意单个字符,文档中每个字符都可以理解为任意字符
grep "r..t" user  //找rt之间有2个任意字符的行
grep "r.t" user  //找rt之间有1个任意字符的行,没有匹配内容,就无输出
grep "*" user  //错误用法,*号是匹配前一个字符任意次,不能单独使用
grep "ro*t" user  //找rt,中间的o有没有都行,有几次都行
grep ".*" user   //找任意,包括空行 .与*的组合在正则中相当于通配符的效果

grep "ro\{1,2\}t" user    //找rt,中间的o可以有1~2个
grep "ro\{2,6\}t" user    //找rt,中间的o可以有2~6个
grep "ro\{2,\}t" user     //找rt,中间的o可以有2个以及2个以上
grep "ro\{1,\}t" user     //找rt,中间的o可以有1个以及1个以上
grep "ro\{3,\}t" user     //找rt,中间的o可以有3个以及3个以上
grep "ro\{2\}t" user      //找rt,中间的o必须只有有2个
grep "ro\{1\}t" user       //找rt,中间的o必须只有有1个  
grep "ro\{3\}t" user        //找rt,中间的o必须只有有3个

grep "\(0:\)\{2\}" user  //找连续的2个0:  小括号的作用是将字符组合为一个整体


以上命令均可以加-E选项并且去掉所有\,改成扩展正则的用法,比如
grep "ro\{1,\}t" user可以改成 grep -E "ro{1,}t" user    
或者
egrep "ro{1,}t" user   

grep "ro\{1,\}t" user    //使用基本正则找o出现1次以及1次以上
egrep "ro{1,}t" user  //使用扩展正则,效果同上,比较精简
egrep "ro+t" user   //使用扩展正则,效果同上,最精简
grep "ro\{0,1\}t" user  //使用基本正则找o出现0~1次
egrep "ro{0,1}t" user   //使用扩展正则,效果同上,比较精简
egrep "ro?t" user  //使用扩展正则,效果同上,最精简

egrep "root|^bin" user   //找有root或者以bin开头的行
cat  aa   //素材文件,里面有一些"the"
the
there
the6
the_
123the
egrep "the\b" aa    //在aa文件中找the,右边不允许出现数字、字母、下划线
egrep "\bthe\b" aa  //找the,两边都不允许出现数字、字母、下划线

sed 流式编辑器
对文档进行非交互式增删改查的操作
逐行处理
用法1:前置命令 | sed  [选项]  '条件指令'
用法2:sed  [选项]  '条件指令'  文件.. ..
选项:
-n  屏蔽默认输出   -r  支持扩展正则  -i 修改源文件
指令:
p  输出    d  删除    s替换
sed -n 'p' user    //输出所有行
sed -n '1p' user   //输出第1行
sed -n '2p' user   //输出第2行
sed -n '3p' user    //输出第3行
sed -n '2,4p' user   //输出2~4行
sed -n '2p;4p' user   //输出第2行与第4行
sed -n '2,+1p' user   //输出第2行以及后面1行
sed -n '/^root/p' user   //输出以root开头的行  
sed -n '/root/p' user   //输出包含root的行
sed -nr '/^root|^bin/p' user
将以上语句中的p指令改为d指令可以实现对应行的删除效果
比如sed -n '2p' user 改成 sed '2d' user  是删除第2行
sed -n '2!p' user   //输出除了第2行的内容,加!是取反效果
sed '3,+1!d' user     //删除第3行、第4行以外的行
sed -n '=' user      //显示行号,=号在sed中可以显示行号
sed -n '$=' user   //查看文档最后一行的行号,相当于查看文档总行数

sed -i '$d' user   //删除文档的最后一行并保存

sed 's/2017/6666/' test.txt   //把所有行的第1个2017替换成6666
sed 's/2017/6666/2' test.txt  //把所有行的第2个2017替换成6666
sed '1s/2017/6666/' test.txt  //把第1行的第1个2017替换成6666
sed '3s/2017/6666/3' test.txt  //把第3行的第3个2017替换成6666
sed '3s/2017//3' test.txt  //把第3行的第3个2017替换成空,相当
于删除
sed '/2024/s/2017/6666/' test.txt  //找到有2024的行,将2017替换
成6666
----------------------------------
尝试将user文档中/bin/bash替换成/sbin/sh
sed '1s//bin/bash//sbin/sh/' user   //直接替换,报错
sed '1s/\/bin\/bash/\/sbin\/sh/' user  //使用转义符号可以
成功,但不方便
sed '1s!/bin/bash!/sbin/sh!' user  //最佳方案,更改s的替换符
sed '1s@/bin/bash@/sbin/sh@' user  //替换符号可以用所有
数字键上的
--------------------------------------
编写脚本,安装httpd服务,需要使用82号端口开启
#!/bin/bash
yum -y install httpd &> /dev/null
sed -i '/^Listen 80$/s/0/2/' /etc/httpd/conf/httpd.conf   //将以Listen 80开
头的行的0换成2
systemctl restart httpd
systemctl enable httpd

echo "web-test~~~"  >  /var/www/html/index.html
setenforce 0  //执行完脚本后,关闭selinux
systemctl stop firewalld  //关闭防火墙
curl 192.168.4.7:82  //测试82端口访问页面
sed替换的高级应用
1)删除文件中每行的第二个、最后一个字符
sed 's/.//2;s/.$//' test    //分两个步骤完成,中间用分号隔开,第一步将每行的第二个任意字符替换成空,第二步将每行的最后一个任意字符替换成空即可
 
2)删除文件中所有的数字
sed 's/[0-9]//g' nssw.txt
 
3)将文件中每行的第一个、倒数第1个字符互换
() 保留(复制)
实现思路:
echo abc > abc                            //创建素材
sed -r 's/(a)(b)(c)/\3\2\1/' abc  //替换abc时复制每一个字符,后面替换的内容用\数字粘贴,可以任意调换位置
echo xyz >> xyz   //追加内容
sed -r 's/(a)(b)(c)/\3\2\1/' abc  //再用之前的方法无法替换第2行
sed -r 's/(.)(.)(.)/\3\2\1/' abc  //将具体字符用 . 替代即可,然后,再将追加abcd时,上述方案失灵
sed -r 's/^(.)(.*)(.)$/\3\2\1/' abc   //再次升级,分别找到第1个字符和最后1个字符,中间可以是任意
sed -r 's/^(.)(.*)(.)$/\3\2\1/'  nssw.txt   //达成需求
 
4)为文件中每个大写字母添加括号
sed -r 's/([A-Z])/(\1)/g'  nssw.txt  //先找到任意大写字母,然后保留,最后替换成带括号的状态
 
编写脚本,安装httpd服务,使用82号端口
#!/bin/bash
yum -y install httpd   //装包
cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bak   //备份配置文件
sed -i '/Listen 80/s/0/2/' /etc/httpd/conf/httpd.conf   //修改配置文件
systemctl restart httpd   //启动服务
 
运行脚本之后,使用curl 192.168.4.7:82测试 或者火狐浏览器192.168.4.7:82
要关闭selinux与防火墙  还可以使用 netstat -ntulp |grep :82查询服务
setenforce 0    //如果脚本执行之前没关闭selinux,会报错
systemctl stop firewalld   //关闭防火墙


sed指令
除了p、d、s之外还有:
a行下追加    i行上添加    c替换整行
sed 'a 666' user    //所有行的下面追加666
sed '1a 666' user   //第1行的下面追加666
sed '/^bin/a 666' user   //在以bin开头的行的下面追加666
sed 'i 666' user  //所有行的上面添加666
sed '5i 666' user   //第5行的上面添加666
sed '$i 666' user  //最后1行的上面添加666
sed 'c 666' user   //所有行都替换成666
sed '1c 666' user  //替换第1行为666

sed 替换文件到另一个文件中的指定行
sed -i '15r a.txt' b.txt  //把啊a.txt的文件替换到b.txt的15行
 ------------------------------------------------------------------------
编写脚本,找到系统使用bash的账户名,然后按照
用户名 --> 密码的格式存储在一个文件中
grep "bash$" /etc/passwd | sed 's/:.*//'    //找到以bash结尾的用户
再用sed去掉用户后面:开始的所有内容,留下的就是用户名
sed -n '/bash$/s/:.*//p' /etc/passwd  //用sed找到以bash结尾的用户
然后去掉用户后面:开始的所有内容,最后加p的作用是仅仅显示被
替换的行
#!/bin/bash
u=$(sed -n '/bash$/s/:.*//p' /etc/passwd)   //在文档中找到以bash结尾的行
并且将行中:以及:后面的所有内容替换为空,留下的就是用户的名字,然后将
这些名字放入变量u里面
for i in $u   //把上一步找到的用户放入循环
do
    pass=$(grep $i /etc/shadow)    //将每个人的密码信息找出
    pass1=${pass#*:}    //掐头
    pass2=${pass1%%:*}   //去尾,得到密码
    echo "$i --> $pass2"  >>  /opt/user.txt  //按格式存在一个文档里
done
awk  精确搜索  逐行处理(二次处理)
格式1:前置指令 | awk [选项] '[条件]{指令}' 
格式2:awk [选项] '[条件]{指令}' 文件
指令: print 输出
选项:-F 定义分隔符
内置变量: $1第1列  $2第2列  $3 ... $0所有列   NR行号   NF列号
awk '{print $1}'  test.txt  //输出所有行的第1列
awk '{print $3}'  test.txt  //输出所有行的第3列
awk '/the/{print $3}'  test.txt  //输出有the的行的第3列
awk '/the/{print NR}'  test.txt  //输出有the的行的行号
awk '{print NR}'  test.txt  //输出所有行的行号
awk '{print NF}'  test.txt  //输出所有行的列号
awk '{print $0,NR}'  test.txt  //输出所有列然后空格输出行号
head -5 /etc/passwd > user
awk -F: '{print $1}' user   //使用-F:修改分隔符为冒号,输出第1列
awk -F: '{print $1,$7}' user  //使用-F:修改分隔符为冒号,输出第1列空格第7列
awk -F: '{print $1,"的解释器是",$7}' user   //输出常量加引号
练习:
使用awk收集网卡流量信息
ifconfig eth0  | awk '/RX p/{print "服务器eth0网卡的接收流量是"$5"字节"}'
ifconfig eth0  | awk '/TX p/{print "服务器eth0网卡的发送流量是"$5"字节"}'
收集根分区剩余容量
df -h | awk '/\/$/{print "根分区剩余容量是"$4}'
------------------------------------------------------------------------
awk中的条件
使用正则     ~包含   !~不包含
awk -F: '$6~/bin/{print}' user   //找第6列包含bin的行
awk -F: '$6!~/bin/{print}' user  //找第6列不包含bin的行
使用数字或者字符串
==  !=   >=   >   <=   <
awk -F: 'NR==1{print}' user    //输出第1行
awk -F: 'NR!=3{print}' user     //输出除了第3行以外的行
awk -F: 'NR<4{print}' user     //输出1~3行
awk -F: '$1=="root"{print}' user   //输出第1列等于root的行
awk -F: '$1~/root/{print}' user   //输出第1列包含root的行
3,逻辑组合   &&并且   ||或者
awk -F: '$3<10&&$7~/bash/' /etc/passwd   //输出第3列(UID)小于10并且
第7列包含bash的行,当给了条件输出一整行时{print}可以省略不写
awk -F: 'NR>=2&&NR<=6' /etc/passwd  //输出2~6行
awk -F: '$1~/root/||$3<=5' /etc/passwd  //输出第1列包含root或者UID小
于等于5的行

4,运算
awk 'NR%2==0' user  //输出偶数行

------------------------------------------------------
awk执行额外任务

BEGIN{   }    执行1次,读取文档之前执行
逐行任务     执行n次 ,读取文档时执行
END{   }      执行1次,读取文档之后执行

awk  'BEGIN{   }{   }END{    }'   //使用时基本框架
awk 'BEGIN{print "xyz"}{print "xyz"}END{print "xyz"}'  user   //输出1
个xyz之后再根据user文档的行数输出5个xyz,最后再输出一个xyz

awk 'BEGIN{print "User\tUID\tHome"}' 	//输出表头信息 
awk -F: '{print $1"\t"$3"\t"$6}' user    //输出内容,用户名,uid,家目录
awk 'END{print "总计"NR"行"}' user   //最后输出行数

awk -F: 'BEGIN{print "User\tUID\tHome"}{print $1"\t"$3"\t"$6}
END{print "总计"NR"行"}'  user

--------------------------------------------------------------------------------
使用awk统计网站访问量:
开启httpd服务,80端口或者82端口都可以
使用curl 192.168.4.7:82  多访问几次网站
测试时可以关闭防火墙和selinux
systemctl stop firewalld
setenforce  0
awk '{print $1}' /var/log/httpd/access_log   //可以找出访问者的ip,但是效果不完美,可以用后面的数组方式解决

awk,for,if循环实现高级搜索

awk 中使用if单分支,如果满足条件,就执行指令,不满足就不执行任何指令
if(条件){指令}
awk -F: 'BEGIN{x=0}{if($7~/bash/){x++}}END{print x}'  /etc/passwd  //统计系统中,有多少用户使用了bash,首先定义变量x,然后使用if判断如果每找到一行的$7包含bash,就把x+1,所有逐行任务结束后,最终使用end任务输出x的值,也就是找系统中使用bash作为解释器的用户数量
 
双分支,如果满足条件就执行指令,不满足就执行else后面的指令
if(条件){指令}else{指令}
awk -F: 'BEGIN{x=0;y=0}{if($7=="/bin/bash"){x++}else{y++}}END{print x,y}' /etc/passwd
//统计系统中使用bash作为解释器的用户,和没有使用bash的用户数量,使用if判断如果每找到一行的$7是/bin/bash,就把x+1,否则y+1,最后使用end输出x与y的值
 
多分支
{if (条件){指令}else if (条件){指令}else{指令}}
awk -F: '{if($7=="/bin/bash"){x++}else
if($7=="/sbin/nologin"){y++}else{z++}}END{print x,y,z}' /etc/passwd   //统计系统中使用bash作为解释器的用户,使用nologin的用户,还有其他用户的数量,变量如果作为运算使用,并且初始值是0的 ,可以省略定义过程
 

数组 相当于可以存储多个值的特殊变量
数组名称[下标]=下标对应的值

[root@svr7 opt]# awk 'BEGIN{a[1]=10;a[2]=20;print a[1],a[2]}'   //使用awk测试数组
创建了一个数组名字叫a,分别定义两个下标与对应的两个值,然后
用print查看了a[1]的值和a[2]的值

数组可以用来收集信息
for循环可以循环输出数组的下标

a[abc]=0   a[abc]++    a[abc]=1
a[xyz]=0    a[xyz]++    a[xyz]=1
a[abc]=1    a[abc]++   a[abc]=2
awk '{a[$1]++}END{print a["abc"],a["xyz"]}' abc.txt  //根据上述结果,得到如果
使用{a[$1]++}走完所有行便可收集到a[xyz]=1和a[abc]=2的结果,所以
在最后使用END任务输出a[abc]和a[xyz]的值就是 2和 1

awk '{a[$1]++}END{for(i in a){print i,a[i]}}' abc.txt  //使用for循环,循环显示
数组a的下标,与值,其中for(i in a)里面的i是变量,代表下标,in是语法不
能变,a是数组名

awk '{a[$1]++}END{for(i in a){print i,a[i]}}' /var/log/httpd/access_log  //将上述
的abc.txt文件替换成网站的日志,就可以最终用来查看日志得到可以得到
哪个ip来访以及来访的次数

awk '{ip[$1]++}END{for(i in ip){print ip[i],i} }'  /var/log/httpd/access_log  | sort -nr
查看日志中某个ip的出现次数,以及ip,然后按降序排列,出现次数最大的
显示在第一行,sort命令可以实现排序效果,-n是以数字排序,-r是降序

awk '/Failed password for root/{ip[$11]++}END{for(i in ip){print ip[i],i}}' /var/log/secure
//查看哪个ip登录root账户时输入错了密码,先输出次数,再输出ip

编写监控脚本,可以查看各种服务器的信息
#!/bin/bash
while :
do
clear     //清屏
ifconfig eth0  | awk '/RX p/{print "服务器eth0网卡的接收流量是"$5"字节"}'
ifconfig eth0  | awk '/TX p/{print "服务器eth0网卡的发送流量是"$5"字节"}'
df -h | awk '/\/$/{print "根分区剩余容量是"$4}'
awk 'END{print "服务器账户总数是"NR"个"}' /etc/passwd
echo "当前已登陆账户数量是$(who | wc -l)个"
free -h | awk '/^Mem:/{print "服务器内存剩余容量是"$4}'
uptime | awk '{print "cpu的15分钟平均负载是"$NF}'
echo "服务器安装软件包数量是$(rpm -qa | wc -l)个"
sleep 3    //休息3秒
done

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值