shell编程三剑客之awk sed超细讲解

shell编程三剑客(文本处理软件)

  • grep --》egrep 文本过滤—》查询
  • awk 文本截取
  • sed 文本替换和修改

1.awk可以进行整数小数运算

echo |awk ‘{print 90+100.1}#单引号一定要为中文

2.-F 指定分隔符(输入分隔符–》FS、输出分隔符OFS)
FS=filed separater
字符串输出拼接:

awk -F: 'OFS="---"{print $1,$4}' /etc/passwd
#结果:
root---0
bin---1
daemon---2
adm---4

awk -F: '{print"username:" $1,"uid:"$4}' /etc/passwd
#结果:
username:root---0
username:bin---1
username:daemon---2
username:adm---4

3.awk完整语法
awk -F 分隔符 ‘/模式/{动作}’ 输入文件
注意:模式以 / / 分割
$0 -->输出一整行

在这里插入图片描述

awk -F: 'BEGIN{print "##start##"} /bash/{print $1,$2} END{print "##end##"}' /etc/passwd

#结果:
##start##
root x
liuyq x
sc_liuyq x
##end##

#只接模式 类似于grep
awk '/bash/' /etc/passwd
结果:
root:x:0:0:root:/root:/bin/bash
liuyq:x:1000:1000::/home/liuyq:/bin/bash
sc_liuyq:x:1001:1001::/home/sc_liuyq:/bin/bash

4.awk 结合正则表达式

#/^h/  以h开头
#/ ^[abc] /  以a、b、c开头的
#/^[^abc]/ 取反 不是以a、b、c开头的
# !取反
#精确匹配 ==
#模糊匹配 ~包含    ~!不包含
#单词的界定 \< 以什么开头 \>以什么结尾 
awk -F: '/^[abc]/{print $1}' /etc/passwd
#结果:
bin
adm
chrony

#模糊匹配
awk -F: '$1 ~ /liu/{print $1,$2}' /etc/passwd
结果:
liuyq x
sc_liuyq x

#单词的界定
awk -F: '$1 ~ /\<liu/{print $1,$2}' /etc/passwd
#结果:
liuyq x

awk -F: '$1 ~ /liuyq\>/{print $1,$2}' /etc/passwd
#结果:
liuyq x
sc_liuyq x

#位数限定1
awk -F: '$4 ~ /\<....\>/{print $1,$4}' /etc/passwd
结果:
liuyq 1000
sc_liuyq 1001
#经典正则
awk -F: '$3 ~ /\<[0-9]{3}\>/{print $1,$3}' /etc/passwd
#结果:
systemd-coredump 999
systemd-resolve 193
polkitd 998
unbound 997

5.awk 命令操作符
在这里插入图片描述

#产生100以内的数 打印出整除5 或者 以1开头的数字
seq 100 | awk '$1%5==0||$1 ~ /^1/{print $1}'

#在passwd文件里找出 uid大于500 小于600 且名字包含liu
awk -F: '$3>=500 && $3<=6000 && $1 ~ /liu/{print $1,$3}' /etc/passwd
#结果:
liuyq 1000
sc_liuyq 1001

#查看进程截取字段
time ps aux|awk '$2<=20{print $11 ,$2}'
#结果:
/usr/lib/systemd/systemd 1
[kthreadd] 2
[rcu_gp] 3
[rcu_par_gp] 4
[kworker/0:0H-kblockd] 6
[kworker/u256:0-events_unbound] 7

awk -F: 'BEGIN{print i=0}$1 ~ /o/{i++;print i,$1}END{print i}' /etc/passwd
#结果:
0
1 root
2 daemon
3 shutdown
4 operator
5 nobody
6 systemd-coredump
7 systemd-resolve
8 polkitd
9 unbound
10 chrony
10

5.awk内置变量

  • NR 记录每行行号 number of recrod
  • NF 记录每行字段数 number of filed $NF取最后一个字段
#输出行号 字段数
awk -F: '{print i,$1,NR,NF}' /etc/passwd
#结果:
 root 1 7
 bin 2 7
 daemon 3 7
 adm 4 7
 lp 5 7
 sync 6 7

6.awk 引入变量(相当于进程和进程之间通信)
进程和进程之间通信的方式?

  1. 信号
  2. 信号量
  3. 管道
  4. socket
  5. 共享内存
  6. 队列
    awk使用管道进行进程之间的通信
name=meinv
echo |awk -v new_name=$name '{print new_name}'
#结果:
meinv


7.awk内置的函数:
length()
int()
sqrt()
system()
String Functions
sub()
index()
length()
split()

[root@swarm ~]# echo |awk '{print rand()}'
0.237788
[root@swarm ~]# echo |awk '{print rand()*100}'
23.7788
[root@swarm ~]# echo |awk '{print int(rand()*100)}'
23

8.流程控制 flow control

找出用户名的字母为3个
[root@swarm ~]# awk -F: '{if($1~/\<...\>/)print $0}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin

题目练习

1.统计名字里包含a字母的用户的数量,输出用户名和uid

awk -F: 'BEGIN{print i=0} $1 ~/a/{i++;print $1,$2}END{print i}' /etc/passwd
#结果:
0
daemon x
adm x
halt x
mail x
operator x
games x
6

2.统计/etc/passwd 文件里的使用bash的用户的个数,并且还要显示出来这些行

awk -F: 'BEGIN{ i=0}  /bash$/{i++;print $0}END{print "total:" i}' /etc/passwd
#结果:
root:x:0:0:root:/root:/bin/bash
liuyq:x:1000:1000::/home/liuyq:/bin/bash
sc_liuyq:x:1001:1001::/home/sc_liuyq:/bin/bash
total:3

3.输出5到8行

awk -F: 'NR>=5&&NR<=6{print $0}' /etc/passwd
#结果:
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

4.使用awk计算seq 20产生的序列的和

[root@localhost ~] seq 100 |awk 'BEGIN{sum=0}{sum+=$1}END{print sum}'
#结果:
5050

5.使用awk显示ens33的入站流量和出站流量(字节) --》ifconfig --》安装net-tools软件包

[root@localhost ~] ifconfig|awk 'NR==5||NR==7{print $5}'
#结果:
9165688
270292

6.使用awk命令统计以r开头的用户数目,显示如下效果

[root@swarm ~]# cat /etc/passwd|awk -F: 'BEGIN{i=0}$1~/^r/{print $1;i++}END{print i}' 
root
rpc
rpcuser
redis
4

7.查看哪些用户没有设置密码,并统计一下个数

[root@swarm ~]# cat /etc/shadow|awk -F: 'BEGIN{i=0}length($2)<=2{print $1,"没有设置密码";i++}END{print "一共有:"i"个用户"}'
bin 没有设置密码
daemon 没有设置密码
adm 没有设置密码
lp 没有设置密码
redis 没有设置密码
一共有:28个用户

8.使用NF变量显示passwd文件倒数第二列的内容

cat passwd|awk -F: '{print $(NF-1)}'

9.显示passwd文件中第5到第10行的用户名

cat passwd|awk -F: 'NR>4 && NR<11 {print $1}'

10.显示passwd文件中第7列不是bash的用户名

passwd|awk -F: 'NR>4 && NR<11 {print $1}'

11.显示passwd文件中行号是5结尾的行号和行

cat passwd|awk -F: 'NR ~ /5$/{print NR,$0}'

12.用ip add只显示ip(不能使用tr或者cut命令)

ifconfig |head -8 |awk  '$0 ~ /RX.*bytes|TX.*bytes/{print $5}'

[root@localhost lianxi]# yum install net-tools -y
13.先使用ifconfig,使用awk显示eth0的入站流量和出站流量(字节)

[root@localhost ~]# ifconfig |head -8 |awk  '$0 ~ /RX.*bytes|TX.*bytes/{print $5}'
9071275
974762

14使用awk命令统计以r开头的用户数目,显示如下效果

[root@localhost ~]# cat /etc/passwd|awk -F: 'BEGIN{i=0} $1 ~ /^r/{print $1;i++}END{print i}'
root
rngd
rooy
3

15./etc/passwd
$3 是uid 用户的编号
如果用户的编号是0 --》管理员
1~999 --》程序用户
大于1000 —》普通用户
最后统计出有多少管理员,多少程序用户,多少普通用户?

cat /etc/passwd|awk  -F: 'BEGIN{i=0;a=0;b=0}{if($3==0)print "管 理员",i++;else if($3<=999&&$3>0)print "程序用户",a++;else print "普通用户",b++}END{print "管理员有"i,"程序用户有"a,"普通用户有"b}'

[root@localhost ~]# awk -F: 'BEGIN{a=b=c=0}{if($3==0)print "管理员",a++;else if($3>=1&&$3<=999)print "程 序用户",b++;else if($3>1000)print "普通用户",c++}END{print "管理员有个"a,"程序用户有个"b,"普通用户有 个"c}'  /etc/passwd

if (表达式 )  {
  语句;语句;...
}  else  if (表达式 )  {
  语句;语句;...
}  else  if (表达式 )  {
  语句;语句;...
}  else  {
  语句;语句;...
}

sed流文本处理工具

pattern space 处理数据的地方
hold space 临时存放数据的地方
sed的常用选项
-n:只显示匹配处理的行(否则会输出所有) *
-e:执行多个编辑命令时(一般用;代替)
-i:直接在文件中进行修改,而不是输出到屏幕 *
-r:支持扩展正则表达式
-f:从脚本文件中读取内容并执行(文件中的编辑命令每行一个,不用;隔开)

[root@swarm ~]# cat -n /etc/passwd  |sed -n '3,5p'
     3	daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4	adm:x:3:4:adm:/var/adm:/sbin/nologin
     5	lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

sed的常用编辑命令
p:打印匹配行 print
d:删除指定行 delete
a:在匹配行后面追加 append
i:在匹配行前面插入 insert
c:整行替换
r:将文件的内容读入 read
w:将文本写入文件 write
s:字符串替换(匹配正则表达式)substitution
= :输出行号

在这里插入图片描述

[root@swarm sed_test]# cat -n /etc/passwd |sed -n "${num1},${num2}p"
     6	sync:x:5:0:sync:/sbin:/bin/sync
     7	shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
     8	halt:x:7:0:halt:/sbin:/sbin/halt
     9	mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    10	operator:x:11:0:operator:/root:/sbin/nologin

[root@swarm sed_test]# cat -n /etc/passwd |sed -n '/bash/p'
     1	root:x:0:0:root:/root:/bin/bash
    24	sanchuang:x:1000:1000::/home/sanchuang:/bin/bash

[root@swarm sed_test]# df -h|sed -n '/\/$/p'
/dev/mapper/centos-root   17G  8.2G  8.9G  49% /

[root@swarm sed_test]# df -h|egrep "/$"
/dev/mapper/centos-root   17G  8.2G  8.9G  49% /

[root@swarm sed_test]# cat /etc/passwd|sed -n '/^[a-Z]/p'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

不以字母开头
[root@swarm sed_test]# cat /etc/passwd|sed -n '/^[^a-Z]/p

防火墙:
在这里插入图片描述

在这里插入图片描述

[root@swarm nginx]# cat access.log|awk -F"[()]" '{print $2}'|uniq
Windows NT 10.0; Win64; x64
[root@swarm nginx]# cat access.log|awk -F"[()]" '{print $2}'|uniq -c
     24 Windows NT 10.0; Win64; x64

cat /etc/passwd|sed -n '/denghui/d'

在这里插入图片描述

题目:

1.步长值

步长值:
[root@localhost ~]# cat  -n /etc/passwd|sed -n '1~2p'  单数行
[root@localhost ~]# cat  -n /etc/passwd|sed -n '2~2p'  双数行

2.shell变量传到sed里

[root@swarm nginx]# cat -n /etc/passwd |sed -n "${num1},${num2}p"
     3	daemon:x:2:2:daemon:/sbin:/sbin/nologin
     4	adm:x:3:4:adm:/var/adm:/sbin/nologin
     5	lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
     6	sync:x:5:0:sync:/sbin:/bin/sync

3.awk sed grep 查找

[root@localhost ~]# cat /etc/passwd|sed -n '/bash/p'
[root@localhost ~]# cat /etc/passwd|egrep "bash"
[root@localhost ~]# cat /etc/passwd|awk  '/bash/'

4.access.log

[root@localhost nginx]# cat  access.log|awk -F'[()]' '{print $2}'
[root@localhost nginx]# cat  access.log|awk -F'[()]' '{print $2}'|sort|uniq -c|sort -nr


cat access.log|sed  -n '/09\/Jan\/2021:16:(3[789]|4[0-9]|5[01]):(0[1-9]|[1-5][0-9])/p'
                                             分钟的范围37~51         秒的范围01~59

5.seLinux关闭 整行替换c

[root@swarm ~]# sed  -i '/^SELINUX=/c SELINUX=disabled' selinux

6.在前面加sanchuang

[root@swarm ~]# sed -i 's/^/sanchuang/' passwd

总结:
sed的查找方式:
1.根据行号
2.根据模式

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值