简述linux输入输出过程,Linux命令之awk:高级输入输出(四)

1、awk输出匹配行的上下行

输出匹配行的上一行语句

awk '/匹配/{print a}{a=$0}'

【原理分析】:

这个awk脚本里有两个大括号,第一个表示匹配到了关键字后才会执行print s;而第二个没有限定,即每一行都会执行s=$0。举个例子,文件abc总共三行,如下:

a

b

c

执行命令awk’/c/{print s}{s=$0}’ abc

输出结果为c 的前一行 b,分析如下:

第一行为a,无法匹配关键字c,所以不执行print s,只执行后面大括号里的内容即将第一行“a” 赋值给变量s;

第二行为c,还是无法匹配到关键字c,不执行print s,只执行s=$0,将第二行“b”赋值给变量s;

第三行为c,可以匹配关键字c,执行命令print s,此时变量s的值为刚刚赋值的“b”,所以输出“b”;之后还会将第三行的全部内容“c”赋值给变量s。

这样就实现了打印关键字的前一行的内容。

[root@sxooky ~]# cat test.txt

300swkchuyaoxianjie$7000

400zbjwanshuatianting$9500

500nmwchiyaoyaojie$6000

200awkworkingbeijng$6000

600catworkingbeijing$9500

100mkworkingbeijing$9500

[root@sxooky ~]# awk '/zbj/{print a}{a=$0}' test.txt

300swkchuyaoxianjie$7000

输出匹配行的下一行语句

awk '/匹配/{a=NR+1}{if(NR==a)print $0}'

【原理分析】:

与上原理差不多,这个awk脚本里有两个大括号,第一个表示匹配到了关键字后才会执行变量a赋值;而第二个没有限定,即只要条件满足,则都会执行print $0。

注:NR为内置变量(当前行号)

找出匹配行的行号b=NR

找出输出行的行号a=b+1

指定输出行号打印

[root@sxooky ~]# cat test.txt

300swkchuyaoxianjie$7000

400zbjwanshuatianting$9500

500nmwchiyaoyaojie$6000

200awkworkingbeijng$6000

600catworkingbeijing$9500

100mkworkingbeijing$9500

[root@sxooky ~]# awk '/zbj/{a=NR+1;next}{if(NR==a)print $0}' test.txt

500nmwchiyaoyaojie$6000

2、awk输出跳过匹配行:

next:跳过匹配行,读取下一条纪录

[root@sxooky ~]# cat -n test.txt

1web:www.baidu.com

2ip=192.168.1.2

3gateway=192.168.1.1

4web:www.163.com

5ip=192.100.100.2

6gateway=192.100.100.1

7web:www.qq.com

8ip=172.10.2.2

9gateway=172.10.2.1

10web:www.126.com

11ip=10.20.1.2

12gateway=10.20.1.1

[root@sxooky ~]# cat -n test.txt |awk 'NR%2==1{next}{print $0}'

2ip=192.168.1.2

4web:www.163.com

6gateway=192.100.100.1

8ip=172.10.2.2

10web:www.126.com

12gateway=10.20.1.1

next的应用:匹配行与下一条纪录合并

[root@sxooky ~]# cat test.txt |awk '/web/{t=$0;next}{printf "%20s %20s\n",t,$0}'

web:www.baidu.com ip=192.168.1.2

web:www.baidu.com gateway=192.168.1.1

web:www.163.com ip=192.100.100.2

web:www.163.com gateway=192.100.100.1

web:www.qq.com ip=172.10.2.2

web:www.qq.com gateway=172.10.2.1

web:www.126.com ip=10.20.1.2

web:www.126.com gateway=10.20.1.1

3、找出工资与工作地点一样的员工

根据下面内容完成:第1列是员工编号,第2列是员工姓名,第3列是出勤状态,第4列是工作地点,第5列是工资

300swkchuyaoxianjie$7000

400zbjwanshuatianting$9500

500nmwchiyaoyaojie$6000

200awkworkingbeijng$6000

600catworkingbeijing$9500

100mkworkingbeijing$9500

操作方法:

[root@sxooky ~]# cat test.txt

300swkchuyaoxianjie$7000

400zbjwanshuatianting$9500

500nmwchiyaoyaojie$6000

200awkworkingbeijng$6000

600catworkingbeijing$9500

100mkworkingbeijing$9500

[root@sxooky ~]# awk 'BEGIN{print "编号\t姓名\t出勤\t\t地点\t\t工资"}{x=$4$5;m[x]=$0 "\n" m[x];n[x]+=1}END{for(i in m){if(n[i]>1)print m[i]}}' test.txt

编号姓名出勤地点工资

100mkworkingbeijing$9500

600catworkingbeijing$9500

[root@sxooky ~]# awk 'BEGIN{print "编号\t姓名\t出勤\t\t地点\t\t工资"}{x=$4$5;m[x]=$0 "\n" m[x];n[x]+=1}END{for(i in m){if(n[i]>1)print m[i]}}' test.txt |grep -v ^$

编号姓名出勤地点工资

100mkworkingbeijing$9500

600catworkingbeijing$9500

原理解析:

1、《awk BEGIN语句块执行过程》:BEGIN{print “编号\t姓 名\t出勤\t\t地点\t\t工资”}

输出

编号 姓名 出勤 部门 工资

2、《awk PATTERN语句块执行过程》:{x=$4$5;m[x]=$0 “\n” m[x];n[x]+=1}

times 1 :

=> m[xianjie$7000 ]="300swkchuyaoxianjie$7000

"

=> n[xianjie$7000]=+1 => n[xianjie$7000]=1

times 2 :

=> m[tianting$9500]="400zbjwanshuatianting$9500

"

=> n[tianting$9500]=+1 => n[tianting$9500]=1

times 3 :

=> m[yaojie$6000]="500nmwchiyaoyaojie$6000

"

=> n[yaojie$6000]=+1 => n[yaojie$6000]=1

time 4 :

=> m[beijng$6000]="200awkworkingbeijng$6000

"

=> n[beijng$6000]=+1 => n[beijng$6000]=1

time 5 :

=> m[beijing$9500]="600catworkingbeijing$9500

"

=> n[beijing$9500]=+1 => n[beijing$9500]=1

time 6 :

=> m[beijing$9500]="100mkworkingbeijing$9500

600catworkingbeijing$9500

"

=> n[beijing$9500]=1+1 => n[beijing$9500]=2

3、《awk END语句块执行过程》:END{for(i in m){if(n[i]>1)print m[i]}}

数组m的下标有: xianjie$7000、tianting$9500、yaojie$6000、beijng$6000、beijing$9500

for i in m

=> i= xianjie$7000

=> i= tianting$9500

=> i= yaojie$6000

=> i= beijng$6000

=> i= beijing$9500

if n[i] >1

=> n[xianjie$7000]=1         =>  pass

=> n[tianting$9500]=1       => pass

=> n[yaojie$6000]=1          => pass

=> n[beijng$6000]=1         => pass

=> n[beijing$9500]=2        => print m[beijing$9500]

输出

100mkworkingbeijing$9500

600catworkingbeijing$9500

4、管道过滤:|grep -v ^$

过滤最后的空行”\n”

5、最后结果

[root@sxooky ~]# awk 'BEGIN{print "编号\t姓名\t出勤\t\t部门\t\t工资"}{x=$4$5;m[x]=$0 "\n" m[x];n[x]+=1}END{for(i in m){if(n[i]>1)print m[i]}}' test.txt |grep -v ^$

编号姓名出勤部门工资

100mkworkingbeijing$9500

600catworkingbeijing$9500

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值