Awk - 一门有用的小语言

2025-05-26

Awk - 一门有用的小语言

awk 是一种小型但功能强大的编程语言,用于处理文本。它由贝尔实验室的 Aho、Weinberger 和 Kerninghan 开发。

Julia Evans为 做了精彩的介绍awk
AWK漫画

awk 将输入文件扫描为一系列行,并将每行拆分为多个字段。字段分隔符通常为空格,但您可以将其自定义为任何字符。

程序awk是一系列“模式-动作”对,也就是说,程序会检查每一行是否与模式匹配,如果匹配,则执行该行对应的动作。Awk 可以交互使用,也可以运行已保存的程序。

以下是用类似 Python 的伪代码编写的 Awk 的功能:

initialize() # Initializes variables in BEGIN block
for line in input_lines: # Awk divides file / input into a list of lines
    for condition, action in conditions: # A program is a list of condition-action pairs
        if condition(line): #match line against condition
            action() #perform action on match 
Enter fullscreen mode Exit fullscreen mode

以下是 Awk 的一些小片段:

1.你好,世界!

您可以awk内联或通过文件运行程序:

awk 'BEGIN{ print "Hello, World!"}'
Enter fullscreen mode Exit fullscreen mode

或者,您可以将其保存到文件中hello.awk

BEGIN{ print "Hello, World!"}
Enter fullscreen mode Exit fullscreen mode

然后运行它awk -f hello.awk

2. 读取 CSV 并打印特定列

现在让我们做点有用的事!下载这个csv 文件,它是 2010 年洛杉矶市按邮政编码划分的人口普查数据。

从 csv 中读取前 3 行:head -3 2010_Census_Populations_by_Zip_Code.csv

Zip Code,Total Population,Median Age,Total Males,Total Females,Total Households,Average Household Size
91371,1,73.5,0,1,1,1
90001,57110,26.6,28468,28642,12971,4.4
Enter fullscreen mode Exit fullscreen mode

我们将使用以下方法打印总计列awk -F, '{print $2}' 2010_Census_Populations_by_Zip_Code.csv

-F,字段分隔符设置为逗号,因为我们需要用逗号分隔才能获取 CSV 文件中的字段。$n允许您使用第 n 列中的值。

3. 计算一些统计数据

awk 允许使用变量和函数。让我们通过计算整个城市的总人口来了解如何使用它们。

# total.awk
{s += $2}
END {print "Total population:", s}
Enter fullscreen mode Exit fullscreen mode

变量默认初始化为 0。在这里,我们使用一个变量s来保存总数。

运行此脚本awk -F, -f total.awk 2010_Census_Populations_by_Zip_Code.csv,我们得到输出:Total population: 10603988

特殊变量和内置函数

awk 使用一些特殊的变量和函数来使你的程序更加紧凑:

  • NF:一行中的字段数
  • NR:行号
  • $0:整个输入行
  • length:给出字符串中的字符数

现在,我们将计算平均家庭规模,即总人口数除以家庭总数。我们感兴趣的列是 $2 和 $6。
我们还想计算每个邮政编码的平均人口数。我们的脚本:

# stats.awk
{ s += $2; h += $6;}
END {print "Total population:", s, "\nTotal households:", h, "\nAverage household size:", s/h, "\nAverage population per zip code:", s/NR}
Enter fullscreen mode Exit fullscreen mode

NR给出了总行数。但我们不需要标题行。我们可以使用tail命令跳过第一行tail -n +2。运行tail -n +2 2010_Census_Populations_by_Zip_Code.csv | awk -F, -f total.awk结果如下:

Total population: 10603988
Total households: 3497698
Average household size: 3.0317
Average population per zip code: 33241.3
Enter fullscreen mode Exit fullscreen mode

4.模式匹配

到目前为止,我们已经用 awk 做了一些有用的事情,但我们忽略了它最大的优势——模式匹配。我们可以基于字段值、正则表达式和行号进行匹配。

  • 每隔一行打印一次:NR%2 == 0 {print $0}。此处 $0 代表整行。
  • 打印人口 > 100,000 的所有邮政编码:$2 > 100000 {print $1}
  • 打印所有人口 > 10,000 且平均家庭规模 > 4 的邮政编码: 。我们可以使用and$2 > 10000 && $7 > 4 { print $1}组合条件, and 分别代表逻辑&&||

进一步阅读

Awk 还有很多其他功能。以下是一些参考资料:

  • 学习 Awk 的最佳资源是同一三人编写的《AWK 编程语言》。这本书超越了典型的编程语言教程,教你如何使用 Awk 的超能力构建多功能系统,例如关系数据库、解析器、解释器等。

  • 《GNU Awk 有效 Awk 编程手册》一本详尽的参考书。

文章来源:https://dev.to/rrampage/awk---a-useful-little-language-2fhf
PREV
一行 CSS 居中对象
NEXT
一厢情愿的编码