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