AWK是一种处理文本文件的语言,是一个强大的文本分析工具,常用于系统管理、日志分析、报表生成、数据统计等方面。AWK命令的核心思想是针对文件中的每一行进行操作,包括读取、处理和输出数据,因此在使用AWK命令时需要熟悉其各种关键字和内置函数。
下面是一些AWK命令的使用教程,包括NF、NR、BEGIN、END、FS等:
- NF(Number of Fields)
NF
是一个内置变量,表示当前处理行的字段数。在AWK命令中,每一行都可以看作是一个由多个字段组成的记录,字段之间的分割符可以自定义,一般是空格或制表符。通过 NF
变量可以获取当前行的字段数,并对其进行处理。例如,假设要计算一个文件中各行的平均字段数,可以使用以下命令:
复制代码awk '{ total += NF } END { print "Average number of fields per line: ", total/NR} file.txt
该命令将会计算 file.txt
文件中所有行的字段数,并将其相加。在结束时,将会输出文件中所有行的平均字段数。
- NR(Number of Records)
NR
是一个内置变量,表示当前行的行号。在AWK命令中,每一行都可以看作是一个记录,通过 NR
变量可以获取当前处理的记录数,并对其进行处理。例如,假设要在一个文件的每一行前面添加行号,可以使用以下命令:
复制代码awk '{ print NR, $0 }' file.txt
该命令将会输出 file.txt
文件中每一行的行号和内容,并将它们合并成一行。
- BEGIN 和 END
BEGIN
和 END
是AWK命令中的两个特殊模式,分别表示在处理输入之前和之后执行的代码块。在 BEGIN
块中,通常用于初始化环境变量、打印表头等操作;在 END
块中,通常用于收尾工作,如输出汇总信息、关闭文件句柄等操作。例如,假设要在一个文件的开头输出表头并在结尾输出文件中所有行的平均字段数,可以使用以下命令:
复制代码awk 'BEGIN { print "Field1 Field2 Field3 Field4" } { total += NF } END { print "Average number of fields per line: ", total/NR }' file.txt
该命令将会在文件处理前先输出表头,然后逐行计算所有行的字段数,并在结束时输出平均字段数。
- FS(Field Separator)
FS
是一个内置变量,表示字段分隔符。默认情况下,AWK命令以空格或制表符作为字段分隔符,但可以通过修改 FS
变量来自定义分隔符。例如,假设要使用逗号作为字段分隔符来处理一个CSV文件,可以使用以下命令:
复制代码awk 'BEGIN { FS="," } { print $1, $2, $3 }' file.csv
该命令将会读取 file.csv
文件中的每一行,并将其以逗号分割成三个字段,然后输出它们的值。
格式:awk '条件类型1{动作1} 条件类型2{动作2}...' filename
[root@server1 ~]# last -n 5
root pts/0 192.168.31.160 Wed Apr 5 21:19 still logged in
reboot system boot 4.18.0-348.7.1.e Wed Apr 5 21:19 still running
root pts/0 192.168.31.160 Wed Apr 5 00:24 - 00:40 (00:16)
reboot system boot 4.18.0-348.7.1.e Wed Apr 5 00:23 - 00:40 (00:16)
root pts/1 192.168.31.160 Tue Apr 4 23:54 - 23:54 (00:00)
wtmp begins Mon Dec 12 01:34:51 2022
[root@server1 ~]# last -n 5 | awk '{print $1 "\t" $3}'
root 192.168.31.160
reboot boot
root 192.168.31.160
reboot boot
root 192.168.31.160
变量名称 | 代表意义 |
---|---|
NF | 每一行($0)的列数 |
NR | 目前处理的是“第几行”数据 |
FS | 分隔符,默认是空白 |
[root@server1 ~]# last -n 5 | awk '{print $1 "\t lines: " NR "\t columns: " NF}'
root lines: 1 columns: 10
reboot lines: 2 columns: 10
root lines: 3 columns: 10
reboot lines: 4 columns: 11
root lines: 5 columns: 10
lines: 6 columns: 0
wtmp lines: 7 columns: 7
[root@server1 ~]# cat /etc/passwd | head -5
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
[root@server1 ~]# cat /etc/passwd | awk '{FS=":"} $3 < 10 {print $1 "\t" $3}'
root:x:0:0:root:/root:/bin/bash ==> {
FS=":"}第二行才生效
bin 1
daemon 2
adm 3
...
mail 8
[root@server1 ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $3 < 10 {print $1 "\t" $3}'
root 0 ==> BEGIN 设置的条件从第一行开始生效
bin 1
daemon 2
...
mail 8
[root@server1 ~]# cat pay.txt
name 1st 2st 3st
vbird 23000 24000 25000
dmtsai 21000 20000 23000
bird2 43000 42000 42100
[root@server1 ~]# cat pay.txt | \
> awk 'NR==1 {printf "%10s %10s %10s %10s %10s\n",$1,$2,$3,$4,"Total"} \
> NR>=2 {total=$2+$3+$4; printf "%10s %10d %10d %10d %10.2f\n",$1,$2,$3,$4,total}'
name 1st 2st 3st Total
vbird 23000 24000 25000 72000.00
dmtsai 21000 20000 23000 64000.00
bird2 43000 42000 42100 127100.00
echo "Alice 23 80 90
Bob 22 85 92
Cathy 21 78 86
David 24 88 94" > file.txt
- 计算文本文件
file.txt
中第二、三、四列的数字之和,并在处理完文件后输出总和值。其中,{total=$2+$3+$4}
表示在每一行中计算第二、三、四列数字之和,赋值给变量total
;END
块中的{printf "%.2f\n", total}
表示在完成整个文件的处理后,使用格式化字符串将total
变量的值输出到屏幕上,保留两位小数。
[root@server1 ~]# cat file.txt | awk '{total+=$2+$3+$4} END {printf "%.2f\n", total}'
783.00