AWK 列提取

LinuxBeginner
立即练习

简介

在 Linux 中处理结构化文本数据时,例如日志文件、CSV 文件或配置文件,你经常需要提取其中的指定列。例如,你可能只想获取系统文件中的用户名,或 Web 访问日志中的状态码。

用于完成这项任务的主要工具是 awk。

awk 会将文本视为由记录(行)和字段(列)组成的数据。这也是纯文本在 Linux 中仍然非常实用的原因之一:许多管理数据格式既便于人工查看,也便于使用命令行工具处理。

  • 记录通常由换行符分隔。
  • 字段通常由空白字符(空格或制表符)分隔。

「记录和字段」模型是理解 awk 的思维框架。不要把文件只看作原始文本,awk 会将其视为可以直接引用的结构化行和列。

在本实验中,你将学习如何使用 awk:

  1. 选择字段:使用 $1、$2 等提取指定列。
  2. 定义字段分隔符:使用 -F 选项处理由空格以外的字符(例如冒号或逗号)分隔的数据。
  3. 引用最后一个字段:使用 $NF 动态访问一行的末尾字段。

提取第一个字段

先从一个以空格分隔的简单文件开始。我们已经为你创建了 data.txt。

查看文件内容:

cat data.txt

输出:

John 25 Engineer
Alice 30 Manager
Bob 22 Intern

对于 awk,每一行都是一条记录,每个单词都是一个字段:

  • 字段 1($1):姓名(例如 John)
  • 字段 2($2):年龄(例如 25)
  • 字段 3($3):职位(例如 Engineer)

如果只想提取姓名,也就是第一列,就让 awk 打印 $1。

在 awk 中,$1、$2 以及类似表达式表示当前记录中的字段。$0 表示当前整行。字段表示法是 awk 能够简洁处理结构化文本的原因之一。

运行以下命令:

awk '{print $1}' data.txt

输出:

John
Alice
Bob

接下来,将该输出保存到文件中:

awk '{print $1}' data.txt > output1.txt

验证新文件的内容:

cat output1.txt

理解字段分隔方式

现在尝试另一种文件格式:/etc/passwd。该文件存储用户账户信息。

查看 passwd 文件的开头部分:

head -n 3 /etc/passwd

输出类似于:root:x:0:0:root:/root:/bin/bash

注意,这些字段之间没有空格,而是使用冒号(:)分隔。

如果直接对该文件运行默认的 awk 命令,字段将无法正确分割,因为 awk 默认使用空格作为分隔符。

尝试运行:

awk '{print $1}' /etc/passwd > output2.txt
head -n 3 output2.txt

你会看到命令打印出整行内容。由于 awk 找不到空格,它会将整行视为一个字段($1)。

要解决这个问题,需要指定自定义的字段分隔符。

这是实际文本处理中的一个重要经验:工具的效果取决于你是否理解数据格式。如果选择了错误的分隔符,那么你以为正在提取的列,并不是 awk 实际识别到的列。

使用自定义字段分隔符(-F)

要将以冒号分隔的数据转换为可用字段,请使用 -F 标志。

命令 awk -F: 告诉 awk 使用冒号字符作为列之间的分隔符。

-F 选项会改变 awk 在执行打印或其他逻辑之前解析每一行的方式。行被正确分割后,$1 和 $7 等字段引用就能再次表示正确的字段。

现在可以提取指定字段。在 /etc/passwd 文件中:

  • 字段 1 是用户名。
  • 字段 7 是 Shell。

提取用户名和 Shell。使用逗号分隔要打印的多个字段。

awk -F: '{print $1, $7}' /etc/passwd > output3.txt

检查结果:

head -n 5 output3.txt

输出应类似于:root /bin/bash

awk 成功根据冒号分割了每一行,并打印出第一个字段和第七个字段;输出中的两个字段之间由空格分隔。

打印最后一个字段($NF)

有时你并不确定一行中包含多少列,或者列数可能会变化。不过,你可能知道所需数据始终位于最后一列。

awk 提供了一个名为 $NF(字段数量,Number of Fields)的内置变量。

  • NF 存储当前行中的字段数量。
  • $NF 表示最后一个字段的值。

这样可以减少命令对固定列号的依赖。当数据从末尾开始的位置比绝对列号更重要时,NF 和 $NF 通常更加灵活。

使用 $NF 提取 /etc/passwd 的最后一列:

awk -F: '{print $NF}' /etc/passwd > output4.txt

检查输出:

head -n 5 output4.txt

在文件结构保持一致的情况下,输出内容应再次对应 Shell,例如 /bin/bash,这与使用 $7 时相同。使用 $NF 通常更加稳健,因为它会自动适应行末的字段。

总结

在本实验中,你学习了使用 awk 解析文本的基础知识:

  1. 字段提取($N):使用 $1、$2 等访问数据中的单个列。
  2. 字段分隔符(-F):使用 -F 选项处理采用不同分隔符(例如冒号或逗号)的文件。
  3. 最后一个字段($NF):动态访问记录的最后一列。

这些技术可以将原始的结构化文本转换为整洁、可用的数据流,以便进一步处理。