简介
在 Linux 中处理结构化文本数据时,例如日志文件、CSV 文件或配置文件,你经常需要提取其中的指定列。例如,你可能只想获取系统文件中的用户名,或 Web 访问日志中的状态码。
用于完成这项任务的主要工具是 awk。
awk 会将文本视为由记录(行)和字段(列)组成的数据。这也是纯文本在 Linux 中仍然非常实用的原因之一:许多管理数据格式既便于人工查看,也便于使用命令行工具处理。
- 记录通常由换行符分隔。
- 字段通常由空白字符(空格或制表符)分隔。
「记录和字段」模型是理解 awk 的思维框架。不要把文件只看作原始文本,awk 会将其视为可以直接引用的结构化行和列。
在本实验中,你将学习如何使用 awk:
- 选择字段:使用
$1、$2等提取指定列。 - 定义字段分隔符:使用
-F选项处理由空格以外的字符(例如冒号或逗号)分隔的数据。 - 引用最后一个字段:使用
$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 解析文本的基础知识:
- 字段提取(
$N):使用$1、$2等访问数据中的单个列。 - 字段分隔符(
-F):使用-F选项处理采用不同分隔符(例如冒号或逗号)的文件。 - 最后一个字段(
$NF):动态访问记录的最后一列。
这些技术可以将原始的结构化文本转换为整洁、可用的数据流,以便进一步处理。



