sed与awk的那些事儿!

sed与awk的那些事

  • 在这里给大家简单的介绍一下sed和awk的的基本常用选项
  • sed多数用于修改配置文件,并配合脚本使用,实现非交互方式自动部署各种服务。
  • awk有着很厉害的查询功能,下面我们来看看awk的优势吧!

Sed命令可以配合一下参数使用:
p显示 d删除 s替换 -n 屏蔽默认输出 a 行后插入 i 行前插入 c 整行替换

. p是打印输入的意思也就是print单词的首字母:

sed -n ‘p’ /etc/passwd  #输出/etc/passwd的全部配置
sed -n ‘1p’ /etc/passwd  #输入第一行
sed -n ‘1,2p’ /etc/passwd  #输出第一行到第二行
sed -n ‘/^root/p’ /etc/passwd #输出以root开头的行
sed -n ‘1p;4p’ /etc/passwd  #输出第一行和第四行
sed -n ‘/bash$/p’ /etc/passwd  #输出以bash结尾的行

. 首先我们来看下/etc/passwd这个文件的内容

[root@localhost ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
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

执行sed ‘1d’ /etc/passwd #删除/etc/passwd文件中的第一行

[root@localhost ~]#sed ‘1d’ /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

这里我们可以看到确实第一行被我们删除了,让我们再来看一下配置文件

[root@localhost ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
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

有很多人会疑问为什么删除了,配置文件里还有呢?
因为我们执行命令的时候没有加上-i选项,建议初学者慎用-i选项
如果加上-i选项那么配置文件里符合条件的内容就会被删除掉。

即:sed -i ‘1d’ /etc/passwd

d是删除也就是delete单词的首字母:

sed ‘1d’ /etc/passwd  #删除/etc/passwd文件中的第一行
sed ‘1,2d’ /etc/passwd  #删除第一行到第二行
sed ‘/^root/d’ /etc/passwd  #删除以root开头的行
sed ‘1d;4d’ /etc/passwd  #删除第一行和第四行
sed ‘/bash$/d’ /etc/passwd  #删除以bash结尾的行

三. s是替换也就是substitute(代替)单词的首字母:
格式 ‘s/要被替换的内容/替换成什么/’ 文件路径

ed -n ‘63,78s/#//’ a.txt	没加-p不输出
sed -n ‘s/aa/bb/2’ a.txt	将每行的第二个aa换成bb
sed -n ‘s/root/xwh/p’ a.txt	p是输出出来
sed -n ‘s#/bin/bash#/bin/nologin#’ a.txt	用#当分隔符
sed -n ‘65,78s/^/#/’	开头加上注释
sed -n 'sed ‘2s/a/p/2p’ a.txt	替换第二行的第二个a字符为p,后面的p是输出

sed工具的多行文本处理操作:
i: 在指定的行之前插入文本
a:在指定的行之后追加文本
c:整行替换

[root@kube-node1 ~]# vimt a.txt  创建一个测试文件随意写点东西
servername 192.168.4.1
test sed -i -a -c

例子1:

[root@kube-node1 ~]# sed -i '2i hello world! ’ a.txt    在第2行前插入指定内容
[root@kube-node1 ~]# cat a.txt
servername 192.168.4.1
hello world!   这行就是我们用i添加进来的
test sed -i -a -c

例子2:

[root@kube-node1 ~]# sed -i '2a this is a test ’ a.txt    第2行后前插入指定内容
[root@kube-node1 ~]# cat a.txt
servername 192.168.4.1
hello world!   
this is a test      这行就是我们用a添加进来的
test sed -i -a -c

例子3:

[root@kube-node1 ~]# sed -i '3c test test test ’ a.txt    将第3行替换为指定内容
[root@kube-node1 ~]# cat a.txt
servername 192.168.4.1
hello world!   
test test test     
test sed -i -a -c

awk基本使用
NR 指定行 NF指定列 -F 指定分隔符
格式:awk [选项] ‘[条件]{指令}’ 文件

awk{ print $1 $2}’ /root/a.txt	//输出文件第一列和第二列的值 逐行任务
df -h | awk ‘NR==2{print $4}’	//输出第二行第4列的值
awk -F: ‘{print $1,$7}’ /etc/passwd	//以冒号为分隔符
awk -F: ‘{print NR,NF}’ /etc/passwd //输出该文件有多少行,每行有多少列 中间用逗号相隔。逗号是空格,可以加可不加
awk -F: ‘{print $1,“家目录是” $7}’ /etc/passwd	//awk可以输出常量,需要用引号引起来
RX是接受数据量	TX是回复的数据量
ifconfig eth0 | awk ‘/RX p/{print $5}’ //利用正则匹配,过滤包含RX p的行

利用3种方法获得剩余根分区可用的空间

[root@localhost ~]# df -h /
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda1       385G   66G  300G   18% /

方法一:df -h / | tail -1 | awk ‘{print $4}’
方法二: df -h / | awk ‘NR==2{print $4}’
方法三:df -h | awk ‘$3 == “66G”{print $4}’

awk会逐行处理文本,支持在处理第一行之前做一些准备工作(比如先定义一个变量),以及在处理完最后一行之后做一些总结性质的工作(最后喊出变量)
格式:
awk [选项] ‘[条件]{指令}’ 文件
awk [选项] ’ BEGIN{指令} {指令} END{指令}’ 文件
BEGIN行前操作执行一次 awk ‘BEGIN{a=1;print a}’ 中间要用分号间隔,固定格式
{ } 逐行执行,END 行后处理只执行一次
示例:

首先利用BEGIN定义变量a,并过滤以bash结尾的行,有一行a的数就加1,最后输出变量a
[root@localhost ~]#awk 'BEGIN{a=0}/bash$/{a++}END{print a}' /etc/passwd
6

统计全文行数:
[root@localhost ~]# awk 'BEGIN{x=1}{x++}END{print x} ' /etc/passwd
49

输出第3列大于10并且小于20的用户:
[root@localhost ~]# awk -F: '$3>10 && $3<20{print}' /etc/passwd
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

awk分支:

单分支 ‘{ if(条件){编辑指令}}’
双分支 ‘{if (条件){编辑指令}}else{编辑指令}’
多分支 ‘{if (条件) {编辑指令}else if(条件2){编辑指令}}awk -F: '{if($3<=1000){i++}}END{print i} ’ /etc/passwd	
awk -F: ‘{if($3<1000){a++}else{b++}}END{print a,b}’ /etc/passwd	awk -F: ‘{if($7=="/bin/bash"){x++}else{y++}}END{print x,y}’ /etc/passwd
awk -F: ‘BEGIN{x=0;b=0}{if($3>30){x++}else if($3<50){b++}}END{print x,b}’ /etc/passwd

数组:
格式:
for(变量 in 数组名){print 变量,数组名[变量]}
awk ‘BEGIN{a1=100;a2=200;print a1,a2}’ 一个下标对应一个值
awk ‘BEGIN{a1=12;a2=13;for (i in a){print i, a[i]}}’
遍历数组:
cat a.txt
abc 对应 a[abc]=1
xyz 对应 a[xyz]=1
xyz 对应 a[xyz]=2
abc 对应 a[abc]=2
opq 对应 a[opq]=1
abc 对应 a[abc]=3
{a[$1]++} //数组名可以任意,逐行任务收集数据
awk ‘{a[$1]++}END{for(i in a){print i,a[i]}}’ a.txt
循环的是下标

[root@kube-node1 ~]# cat a.txt //做一个素材使用以下是内容
abc 192.168.0.1
xyz 192.168.0.2
xyz 192.168.0.2
abc 192.168.0.1
opq 192.168.0.3
abc 192.168.0.1

输出各个ip出现了几次

格式 ‘{ }END{ for ( ) {print }}’
[root@kube-node1 ~]# awk ‘{ip[$2]++}END{for (i in ip){print i,ip[i]}}’ a.txt

举例查出/var/log/httpd/acces_log中哪个ip访问了几次?

[root@svr5 ~]# awk ‘{ip[$1]++}{for(i in ip)}{print i ,ip[i]}’ /var/log/httpd/acces_log | grep sort -nr	
-n 是正序 -r 是倒叙

下面我们用AWK写一个脚本来获取服务器硬件信息

[root@svr5 ~]# vim test.sh
#!/bin/bash
ip=ifconfig eth0 | awk '/inet /{print $2}'
echo “本地IP地址是:”$ip
cpu=uptime | awk '{print $NF}'
echo "本机CPU最近15分钟的负载是:"$cpu
net_in=ifconfig eth0 | awk '/RX p/{print $5}'
echo “入站网卡流量为:”$net_in
net_out=ifconfig eth0 | awk '/TX p/{print $5}'
echo “出站网卡流量为:”$net_out
mem=free | awk '/Mem/{print $4}'
echo “内存剩余容量为:$mem
disk=`df | awk '/\/$/{print $4}'`
echo "根分区剩余容量为:"$disk
user=`cat /etc/passwd |wc -l`
echo "本地账户数量为:"$user
login=`who | wc -l`
echo "当前登陆计算机的账户数量为:"$login
process=`ps aux | wc -l`
echo "当前计算机启动的进程数量为:"$process
soft=`rpm -qa | wc -l`
echo "当前计算机已安装的软件数量为:"$soft

最后让我们一起来运行这个脚本吧!

[root@localhost ~]# bash test.sh
本地IP地址是:192.168.71.128
本机CPU最近15分钟的负载是:0.05
入站网卡流量为:2179218
出站网卡流量为:110655
内存剩余容量为:11239072
根分区剩余容量为:314253608
本地账户数量为:48
当前登陆计算机的账户数量为:3
当前计算机启动的进程数量为:228
当前计算机已安装的软件数量为:1578
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章