前言
awk是一个非常棒的数据处理工具,相较于sed常常作用于一整行的处理,awk则比较倾向于一行当中分成数个字段来处理,因此,awk相当适合处理小型的文本数据。
awk工作原理
逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。
sed命令常用于一整行的处理,而awk比较倾向于将一行分成多个“字段”然后再进行处理。awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。在使用awk命令的过程中,可以使用逻辑操作符“&&”表示“与”、“||”表示“或”、“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别表示加、减、乘、除、取余和乘方。
命令格式
awk 选项 '模式或条件 {操作}' 文件 1 文件 2 …
awk -f 脚本文件 文件 1 文件 2 …
三.常见的内建变量(可直接用)
FS∶ 列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用相同
NF∶ 当前处理的行的字段个数。
NR∶ 当前处理的行的行号(序数)。
$0∶当前处理的行的整行内容。
$n∶ 当前处理行的第n个字段(第n列)。
FILENAME∶ 被处理的文件名。
RS∶ 行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录,而awk一次仅读入一条记录,以进行处理。预设值是’\n’
FNR:awk当前读取的记录数,其变量值小于等于NR(比如当读取第二个文件时,FNR是从0开始重新计数,而NR不会)。
NR==FNR:用于在读取两个或两个以上的文件时,判断是不是在读取第一个文件。
基本语法
awk [选项参数] 'script' var=value file(s)
或
awk [选项参数] -5.f scriptfile var=value file(s)
参数 注释
-F 指定输入行的分隔符,awk 命令默认分隔符为空格或制表符
-f 从脚本文件中读取 awk 脚本指令,以取代直接在命令行中输入指令
-v 赋值一个用户定义变量
// 匹配代码块,可以是字符串或正则表达式
’ ’ 引用代码块
; 多条命令使用分号分隔
{} 命令代码块,包含一条或多条命令
BEGIN 在 awk 程序一开始,未读取任何数据之前执行。BEGIN 后的动作只在程序开始时执行一次
END 在 awk 程序处理完所有数据,即将结束时执行END 后的动作只在程序结束时执行一次
变量
参数 注释
$0 表示整个当前行
$1 ~ $n 当前记录的第N个字段
FS 输入字段分隔符(默认是空格)
RS 输入记录分割符,默认换行符(即文本是按一行一行输入)
NF 字段个数就是列
NR 记录数,就是行号,默认从1开始
FNR 与NR类似,不过多文件记录不递增,每个文件都从1开始
OFS 输出字段分隔符,默认空格
ORS 输出记录分割符,默认换行符
\n 换行符
~ 匹配正则表达式
!~ 不匹配正则表达式
= += -= *= /= %= ^= **= 赋值
&& 逻辑与
< <= > >= != == 关系运算符
* / % 乘,除与求余
* $ 字段引用
awk实例
参数
参数匹配模式
[root@servera ~]# cat yang.txt
'天生我才必有用'
//空行
[root@servera ~]# awk '/^$/{print "千金散尽还复来"}' yang.txt //匹配空行
千金散尽还复来
记录和字段
awk将每个输入行作为一条记录,而将由空格或制表符分隔的单词(即列)作为字段((用来分隔字段的字符被称为分隔符) (以取本机ip为实例)
[root@servera ~]# 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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:d5:27:49 brd ff:ff:ff:ff:ff:ff
inet 192.168.75.143/24 brd 192.168.75.255 scope global dynamic noprefixroute ens160
valid_lft 1465sec preferred_lft 1465sec
inet6 fe80::124:207:8842:e49d/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@servera ~]# ip a|grep 'inet '|grep -v '127.0.0.1'|awk -F '[ /]+' '{print $3}'
192.168.75.143
字段的划分
awk可以使用三种方法来分割字段
1.第一个方法是用空白字符来分隔字段。将FS设置为一个空格。在这种情况下,记录的前导空白字符和结尾空白字符(空格和/或制表符)将被忽略。并且字段空格和/或制表位来分隔。因为FS的默认值为一个空格,所以这也是通常情况下awk将记录划分为字段的方法。
2.第二个方法是使用其他单个字符来分隔字段。例如,awk程序经常使用“:”作为分隔符。当FS表示任何单个字符时,在这个字符出现的任何地方都将分隔出另外一个字段。如果出现两个连续的分隔符,在它们之间的字段值为空串。
3.第三个方法是,如果你设置了不止一个字符作为字段分隔符,它将被作为一个正则表达式来解释。
[root@servera etc]# cat 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
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
[root@servera etc]# awk 'BEGIN{FS=":"}{print $3}' passwd
0
1
2
3
4
5
6
7
变量
NF
变量定义为当前输入记录的字段个数(即有几列)
//查看磁盘挂载文件每行有多少列
[root@servera etc]# awk '{print NF}' fstab
0
1
2
10
1
9
12
3
11
6
2
6
6
0
6
0
//加个$ ,就是显示最后一个字段/一列 的内容
[root@servera etc]# awk '{print $NF}' fstab
#
/etc/fstab
2020
#
'/dev/disk/'.
info.
lin
systemd
file.
pande
0
0
0
NR
NR是每行的记录号,也就是行号,多文件记录递增
//输出第一行内容并带上行号
[root@servera ~]# awk '{print NR $1}' test.txt
1nsult
2Guide
3savailable
4Look
5Two
6
//用双引号引起来的就是分隔符(这里用空格)
[root@servera ~]# awk '{print NR " " $1}' test.txt
1 nsult
2 Guide
3 savailable
4 Look
5 Two
//这里把1换成0,就是显示全文
[root@servera ~]# awk '{print NR "." $0}' test.txt
1.nsult Section 3.1 in the Owner and Operator.
2.Guide for a description of the tape drive
3.savailable on your system.
4.Look in the Owner and Operator Guide shipped with your system.
5.Two manuals are provided including the Owner and
RS输入的记录分隔符
处理这种包括多行数据的记录,我们可以将字段分隔符定义为换行符,换行符用“\n”来表示,并将记录分隔符设置为空字符串,它代表一个空行。
[root@servera ~]# cat test.txt
nsult Section 3.1 in the Owner and Operator.
Guide for a description of the tape drive
savailable on your system.
Look in the Owner and Operator Guide shipped with your system.
Two manuals are provided including the Owner and
[root@servera ~]# awk 'BEFIN{FS="\n";RS=""}{print $1}' test.txt
nsult
Guide
savailable
Look
Two