AWK

127 阅读3分钟

超强外援:coolshell.cn/articles/90…

当然可以,awk 是一个强大的文本处理工具,广泛用于 Linux 和 Unix 系统中。它可以用于模式匹配、文本转换和报告生成。awk 的语法和功能非常丰富,下面是一些详细的介绍和示例。

基本语法

awk 'pattern { action }' file
  • pattern:可选,指定要匹配的文本模式。
  • action:可选,指定在匹配的行上执行的操作。
  • file:要处理的文件。

如果没有指定 patternawk 会对每一行执行 action。如果没有指定 actionawk 默认打印匹配的行。

基本示例

假设有一个名为 example.txt 的文件,内容如下:

Alice 30
Bob 25
Charlie 35

1. 打印文件的所有行

awk '{ print }' example.txt

2. 打印文件的第一列

awk '{ print $1 }' example.txt

3. 打印文件的第二列

awk '{ print $2 }' example.txt

字段分隔符

默认情况下,awk 使用空格或制表符作为字段分隔符。可以使用 -F 选项指定其他分隔符。

1. 使用逗号作为分隔符

假设有一个文件 data.csv,内容如下:

Alice,30
Bob,25
Charlie,35

打印第一列:

awk -F ',' '{ print $1 }' data.csv

条件匹配

可以使用条件表达式来匹配特定的行。

1. 打印第二列大于30的行

awk '$2 > 30 { print }' example.txt

2. 打印包含 "Alice" 的行

awk '/Alice/ { print }' example.txt

内置变量

awk 有许多内置变量,用于表示当前行和字段的信息。

  • NR:当前行号。
  • NF:当前行的字段数。
  • $0:当前行的全部内容。
  • $1, $2, ...:当前行的第一个、第二个字段,依此类推。

1. 打印行号和行内容

awk '{ print NR, $0 }' example.txt

2. 打印行号和字段数

awk '{ print NR, NF }' example.txt

BEGIN 和 END 块

BEGINEND 块分别在处理输入之前和之后执行。 END的意思是“处理完所有的行的标识”,即然说到了END就有必要介绍一下BEGIN,这两个关键字意味着执行前和执行后的意思,语法如下:

  • BEGIN{ 这里面放的是执行前的语句 }
  • END {这里面放的是处理完所有的行后要执行的语句 }
  • {这里面放的是处理每一行时要执行的语句}

为了说清楚这个事,我们来看看下面的示例:

假设有这么一个文件(学生成绩表):

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

我们的awk脚本如下(我没有写有命令行上是因为命令行上不易读,另外也在介绍另一种用法):

$ cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#运行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

我们来看一下执行结果:(也可以这样运行 ./cal.awk score.txt)

$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  TOTAL:       319      393      350
AVERAGE:     63.80    78.60    70.00

1. 打印文件的头和尾

awk 'BEGIN { print "Start of File" } { print } END { print "End of File" }' example.txt

数学运算

awk 支持基本的数学运算。

1. 计算每行的和

awk '{ sum = $1 + $2; print sum }' example.txt

字符串操作

awk 也支持字符串操作。

1. 拼接字符串

awk '{ print $1 " is " $2 " years old." }' example.txt

使用函数

awk 提供了许多内置函数,如 length()substr()index() 等。

1. 打印每行的长度

awk '{ print length($0) }' example.txt

2. 提取子字符串

awk '{ print substr($1, 1, 3) }' example.txt

综合示例

假设有一个文件 students.txt,内容如下:

Alice 85
Bob 92
Charlie 78
David 88

1. 打印分数大于80的学生

awk '$2 > 80 { print $1 }' students.txt

2. 计算平均分

awk '{ sum += $2 } END { print "Average:", sum/NR }' students.txt

总结

awk 是一个功能强大且灵活的文本处理工具,适用于各种文本处理任务。通过理解其基本语法和功能,可以在数据处理、报告生成和自动化任务中发挥巨大作用。以上介绍只是 awk 功能的冰山一角,深入学习和实践可以帮助你更好地掌握和应用这个工具。