awk命令使用方法
awk工具介绍
awk是一种强大的文本处理工具,它可以对文本文件进行分析和处理。它的名字来源于它的创始人 Alfred Aho、Peter Weinberger 和 Brian Kernighan 的姓氏首字母缩写。
awk可以根据用户指定的规则来处理文本文件,并输出处理结果。
awk的处理过程是逐行读取文件,然后将每行分割成若干个字段,然后对每个字段进行处理。
awk支持多种操作,包括条件判断、循环、数学运算、字符串处理等。
awk 的语法比较简单,但是功能非常强大,可以用来处理各种文本文件。
awk工作原理
1.读取文件:awk 逐行读取输入文件,每次读取一行文本。
2.分割字段:awk 默认使用空格作为字段的分隔符,将每行文本分割成多个字段。可以使用 -F参数指定其他分隔符。
3.匹配模式:awk 使用用户指定的模式来匹配每行文本。模式可以是正则表达式,也可以是字符串。
4.执行动作:当某行文本匹配到指定的模式时,awk 执行对应的动作。动作可以是打印文本、计算数值、处理字符串等。
5.循环处理:awk重复执行上述步骤,直到处理完所有的行。
awk常用的内置变量
内置变量 | 作用 |
---|---|
$0 | 当前处理的行的整行内容。 |
$1、$2、$3 | 当前记录(行)的第一个、第二个、第三个字段。 |
FS | 列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用相同 |
OFS | 输出字段分割符 |
NR | 当前处理的行的行号(序数) |
NF | 当前处理的行的字段个数。$NF代表最后一个字段 |
RS | 行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录, 而awk一次仅读入一条记录进行处理。预设值是’\n ’ |
ORS | 输出记录分隔符。 |
FILENAME | 被处理的文件名 |
awk实例
1.$0:当前处理的行的整行内容。
打印文件所有内容
[root@controller ~]# awk '{print $0}' aa
11111111
hello world
33333333
hello
44444444
55555555
[root@controller ~]#
2.NR:当前处理的行的行号(序数)
打印文件所有内容并显示行号
[root@controller ~]# awk '{print NR,$0}' aa
1 11111111
2 hello world
3 33333333
4 hello
5 44444444
6 55555555
[root@controller ~]#
3.$1,$2,$3:当前记录(行)的第一个、第二个、第三个字段
使用多个字段输出内容
[root@controller ~]# cat bb
HELLO WORLD OP MHY
[root@controller ~]#
[root@controller ~]# awk '{print $1,$2,$3,$4}' bb
HELLO WORLD OP MHY
[root@controller ~]#
切换字段顺序进行输出
[root@controller ~]# cat bb
HELLO WORLD OP MHY
[root@controller ~]#
[root@controller ~]# awk '{print $4,$1,$3,$2}' bb
MHY HELLO OP WORLD
[root@controller ~]#
4.BEGIN 与 END
BEGIN 被放置在没有读取任何数据之前
END 被放置在所有的数据读取完成以后执行
使用BEGIN进行计算
[root@controller ~]# echo a b c d | awk 'BEGIN{one=1;two=2}{print $(one+two)}'
c
[root@controller ~]#
[root@controller ~]# awk 'BEGIN{print 1+2}'
3
[root@controller ~]#
[root@controller ~]# awk 'BEGIN{print 1-2}'
-1
[root@controller ~]#
[root@controller ~]# awk 'BEGIN{print 2*2}'
4
[root@controller ~]#
[root@controller ~]# awk 'BEGIN{print 4/2}'
2
[root@controller ~]#
[root@controller ~]# awk 'BEGIN{print 2**3}'
8
[root@controller ~]#
[root@controller ~]# awk 'BEGIN{print 10%4}'
2
[root@controller ~]#
5.FS:列分割符,指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用相同
使用变量FS改变分隔符
[root@controller ~]# cat bb
HELLO WORLD OP MHY
[root@controller ~]#
[root@controller ~]# awk -F'\t' '{print $2}' bb
OP MHY
[root@controller ~]#
[root@controller ~]# awk 'BEGIN{FS="\t"}{print $2}' bb
OP MHY
[root@controller ~]#
由于将文本中WORLD后面的空格换成了TAB,使用FS改变分隔符后HELLO WORLD就变成了第1个字段,OP MHY就变成了第2个字段。
6.将指定的ip地址取出来
[root@controller ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:80:df:b8 brd ff:ff:ff:ff:ff:ff
inet 192.168.200.10/24 brd 192.168.200.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe80:dfb8/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@controller ~]#
[root@controller ~]#
[root@controller ~]# ip a | grep 'inet ' | grep -v '127'
inet 192.168.200.10/24 brd 192.168.200.255 scope global noprefixroute ens33
[root@controller ~]#
[root@controller ~]# ip a | grep 'inet ' | grep -v '127' | awk -F'[ /]+' '{print $3}'
192.168.200.10
[root@controller ~]#
先匹配inet和空格然后使用-v将127开头这个ip地址取反,这样就只剩下192开头这一行的ip地址了,再用awk将空格和左斜杠作为字段分隔符,将ip地址对应的字段输出就行。
7.OFS:输出字段分割符
[root@controller ~]# cat aa
iohn 85 92 78 94 88
andrea 88 90 75 90 86
jasper 84 88 80 92 84
[root@controller ~]#
[root@controller ~]# awk 'BEGIN{FS=" "}{print $1,$3}' aa
iohn 92
andrea 90
jasper 88
[root@controller ~]#
[root@controller ~]# awk 'BEGIN{FS=" ";OFS=":"}{print $1,$3} ' aa
iohn:92
andrea:90
jasper:88
[root@controller ~]#
使用ofs指定分隔符后,$1和$3中间的逗号会被替换成你指定的分隔符输出,如果$1和$3中间不加逗号就等于没有分隔符,就算你指定了也没用。
8.NF:当前处理的行的字段个数。$NF代表最后一个字段
打印文本每行有多少字段
[root@controller ~]# cat aa
iohn 85 92 78 94 88
andrea 88 90 75 90 86
jasper 84 88 80 92 84
[root@controller ~]#
[root@controller ~]# awk '{print NF}' aa
6
6
6
[root@controller ~]#
打印文本最后一列
[root@controller ~]# cat aa
iohn 85 92 78 94 88
andrea 88 90 75 90 86
jasper 84 88 80 92 84
[root@controller ~]#
[root@controller ~]# awk '{print $NF}' aa
88
86
84
[root@controller ~]#
打印文本倒数第2列
[root@controller ~]# cat aa
iohn 85 92 78 94 88
andrea 88 90 75 90 86
jasper 84 88 80 92 84
[root@controller ~]#
[root@controller ~]# awk '{print $(NF-1)}' aa
94
90
92
[root@controller ~]#
先将NF-1括起来运算,再用 $ 把倒数第2列取出来