awk: 好用的数据处理工具

AWK是一种处理文本文件的语言,是一个强大的文本分析工具,常用于系统管理、日志分析、报表生成、数据统计等方面。AWK命令的核心思想是针对文件中的每一行进行操作,包括读取、处理和输出数据,因此在使用AWK命令时需要熟悉其各种关键字和内置函数。

下面是一些AWK命令的使用教程,包括NF、NR、BEGIN、END、FS等:

  1. NF(Number of Fields)

NF 是一个内置变量,表示当前处理行的字段数。在AWK命令中,每一行都可以看作是一个由多个字段组成的记录,字段之间的分割符可以自定义,一般是空格或制表符。通过 NF 变量可以获取当前行的字段数,并对其进行处理。例如,假设要计算一个文件中各行的平均字段数,可以使用以下命令:

复制代码awk '{ total += NF } END { print "Average number of fields per line: ", total/NR} file.txt

该命令将会计算 file.txt 文件中所有行的字段数,并将其相加。在结束时,将会输出文件中所有行的平均字段数。

  1. NR(Number of Records)

NR 是一个内置变量,表示当前行的行号。在AWK命令中,每一行都可以看作是一个记录,通过 NR 变量可以获取当前处理的记录数,并对其进行处理。例如,假设要在一个文件的每一行前面添加行号,可以使用以下命令:

复制代码awk '{ print NR, $0 }' file.txt

该命令将会输出 file.txt 文件中每一行的行号和内容,并将它们合并成一行。

  1. BEGIN 和 END

BEGINEND 是AWK命令中的两个特殊模式,分别表示在处理输入之前和之后执行的代码块。在 BEGIN 块中,通常用于初始化环境变量、打印表头等操作;在 END 块中,通常用于收尾工作,如输出汇总信息、关闭文件句柄等操作。例如,假设要在一个文件的开头输出表头并在结尾输出文件中所有行的平均字段数,可以使用以下命令:

复制代码awk 'BEGIN { print "Field1 Field2 Field3 Field4" } { total += NF } END { print "Average number of fields per line: ", total/NR }' file.txt

该命令将会在文件处理前先输出表头,然后逐行计算所有行的字段数,并在结束时输出平均字段数。

  1. 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} 表示在每一行中计算第二、三、四列数字之和,赋值给变量 totalEND 块中的 {printf "%.2f\n", total} 表示在完成整个文件的处理后,使用格式化字符串将 total 变量的值输出到屏幕上,保留两位小数。
[root@server1 ~]# cat file.txt | awk '{total+=$2+$3+$4} END {printf "%.2f\n", total}'
783.00

猜你喜欢

转载自blog.csdn.net/dgwxligg/article/details/129979549