Linux 命令实战(六)

2023-10-23 15:51:33 浏览数 (1)

AWK实现原理

当读到第一行时,匹配条件,然后执行指定动作,再接着读取第二行数据处理,不会默认输出。

如果没有定义匹配条件,则是默认匹配所有数据行,awk隐含循环,条件匹配多少次,动作就会执行多少次。

逐行读取文本,默认以空格或tab键为分割符进行分割,将分割所得的各个字段,保存到内建变量中,并按模式或或条件执行编辑命令。

AWK使用格式

代码语言:javascript复制
格式1:  awk  【选项】 '模式或条件{操作} '    文件名

内置函数

内置函数

含义

NR

表示该行的第几行

NF

表示该行有多少列

FNR

读取文件的记录数(行号),从1开始,新的文件重新从1开始计数

FS

字段分隔符,指定每行字段的分隔符,默认空格,相当-F

OFS

表示输出的内容以什么为分割符(默认空格)

RS

行分割符,awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录,而awk一次仅读取一条记录,预设值是“n“

ORS

输出分割符,默认也是换行符

实战练习

演示文件passwd1

代码语言:javascript复制
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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

passwd1 打印行号

代码语言:javascript复制
[root@host1 test]# awk '{print NR}' passwd1
1
2
3
4
5
6
7
8
9
10

passwd1 每列按照:分割,每行有几列

代码语言:javascript复制
[root@host1 test]# awk -F: '{print NF}' passwd1
7
7
7
7
7
7
7
7
7
7

passwd1,passwd2,合并文件,输出文件的序列号

代码语言:javascript复制
[root@host1 test]# awk '{print FNR,$0}' passwd1 passwd2
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
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
1 operator:x:11:0:operator:/root:/sbin/nologin
2 games:x:12:100:games:/usr/games:/sbin/nologin
3 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
4 nobody:x:99:99:Nobody:/:/sbin/nologin
5 systemd-network:x:192:192:systemd Network 

passwd1每列按照:分割,打印第二行的第一列

代码语言:javascript复制
BEGIN:一般用来做初始化操作,仅在读取数据记录之前执行一次
END:一般用来做汇总操作,仅在读取完数据记录之后执行一次
代码语言:javascript复制
[root@host1 test]# awk 'BEGIN{FS=":"}NR==2{print $1}' passwd1bin

passwd1,每列按照:分割,第一列和第二列按照#分割输出(OFS定义了输出时以什么分隔,12中间要用#分隔)

代码语言:javascript复制
[root@host1 test]# awk 'BEGIN{FS=":";OFS="#"}{print $1,$2}' passwd1
root#x
bin#x
daemon#x
adm#x
lp#x
sync#x
shutdown#x
halt#x
mail#x
operator#x

passwd1,定义以:换行打印($0指打印整行)

代码语言:javascript复制
[root@host1 test]# awk 'BEGIN{RS=":"}{print $0}' passwd1
root
x
0
0
root
/root
/bin/bash
bin
x
1
1
bin
/bin
/sbin/nologin
daemon

passwd1,把多行合并成一行输出,输出的时候自定义以空格分隔每行,本来默认的是回车键(ORS-输出分割符,默认也是换行符)

代码语言:javascript复制
[root@host1 test]# awk 'BEGIN{ORS="#"}{print $0}' passwd1
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#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin#sync:x:5:0:sync:/sbin:/bin/sync#shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown#halt:x:7:0:halt:/sbin:/sbin/halt#mail:x:8:12:mail:/var/spool/mail:/sbin/nologin#operator:x:11:0:operator:/root:/sbi
代码语言:javascript复制

演示文件test

代码语言:javascript复制
name       color  amount
apple      red    4
banana     yellow 6
name       color  amount
apple      red    3
banana     yellow 5

计算每种颜色的总金额

代码语言:javascript复制
[root@host1 test]# cat test| grep -v '^name'|awk '{a[$2] =$3}END{ for (i in a){print i,a[i]} }' 
red 7
yellow 11

获取(玩转Git三剑客)视频,关注后回复010,持续关注,如果对您有一丝丝帮助,麻烦点个关注,也欢迎转发,谢谢

0 人点赞