如何使用 AWK 语言在 Linux 中操作文本如何使用 AWK 语言在 Linux 中操作文本如何使用 AWK 语言在 Linux 中操作文本如何使用 AWK 语言在 Linux 中操作文本
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

如何使用 AWK 语言在 Linux 中操作文本

介绍

Linux 实用程序通常遵循 Unix 的设计哲学。鼓励工具小型化,使用纯文本文件进行输入和输出,并以模块化方式运行。由于这一传统,我们使用 sed 和 awk 等工具拥有强大的文本处理功能。

awk 是一种编程语言和文本处理器,您可以使用它以非常有用的方式处理文本数据。在本指南中,您将探索如何使用 awk 命令行工具以及如何使用它来处理文本。

基本语法

awk 命令默认包含在所有现代 Linux 系统中,因此您无需安装它即可开始使用它。

awk 在处理以可预测方式格式化的文本文件时最有用。例如,它非常擅长解析和操作表格数据。它逐行运行并遍历整个文件。

默认情况下,它使用空格(空格、制表符等)来分隔字段。幸运的是,Linux 系统上的许多配置文件都使用这种格式。

awk 命令的基本格式是:

  1. awk '/search_pattern/ { action_to_take_on_matches; another_action; }' file_to_parse

您可以从任何 awk 命令中省略搜索部分或操作部分。默认情况下,如果未给出“action”部分,则采取的操作是“print”。这只是打印所有匹配的行。

如果没有给出搜索部分,awk 执行每行列出的操作。

如果两者都给出,awk 使用搜索部分来决定当前行是否反映了模式,然后对匹配项执行操作。

在最简单的形式中,您可以像使用 cat 一样使用 awk 将文本文件的所有行打印到屏幕上。

创建一个 favorite_food.txt 文件,其中列出了一群朋友最喜欢的食物:

  1. echo "carrot sandy
  2. wasabi luke
  3. sandwich brian
  4. salad ryan
  5. spaghetti jessica" > favorite_food.txt

现在使用 awk 命令将文件打印到屏幕上:

  1. awk '{print}' favorite_food.txt

您将看到打印到屏幕上的文件:

Output
carrot sandy wasabi luke sandwich brian salad ryan spaghetti jessica

这不是很有用。让我们通过在文件中搜索文本 \sand 来尝试 awk 的搜索过滤功能:

  1. awk '/sand/' favorite_food.txt
Output
carrot sandy sandwich brian

如您所见,awk 现在只打印其中包含字符 \sand 的行。

使用正则表达式,您可以定位文本的特定部分。要仅显示以字母 \sand 开头的行,请使用正则表达式 ^sand:

  1. awk '/^sand/' favorite_food.txt

这次只显示一行:

Output
sandwich brian

同样,您可以使用操作部分来指定要打印的信息片段。例如,要仅打印第一列,请使用以下命令:

  1. awk '/^sand/ {print $1;}' favorite_food.txt
Output
sandwich

您可以通过与其列号关联的变量引用每一列(由空格分隔)。例如,第一列是$1,第二列是$2,您可以用$0引用整行。

内部变量和扩展格式

awk 命令在处理文件时使用一些内部变量来分配某些信息。

awk 使用的内部变量是:

  • FILENAME:引用当前输入文件。
  • FNR:引用当前记录相对于当前输入文件的编号。例如,如果您有两个输入文件,这会告诉您每个文件的记录编号而不是总数。
  • FS:用于表示记录中每个字段的当前字段分隔符。默认情况下,这被设置为空白。
  • NF:当前记录的字段数。
  • NR:当前记录的编号。
  • OFS:输出数据的字段分隔符。默认情况下,这被设置为空白。
  • ORS:输出数据的记录分隔符。默认情况下,这是一个换行符。
  • RS:记录分隔符,用于区分输入文件中的不同记录。默认情况下,这是一个换行符。

您可以随意更改这些变量的值以满足文件的需要。通常您在处理的初始化阶段执行此操作。

这给我们带来了另一个重要的概念。 awk 语法比您目前使用的稍微复杂一些 还有可选的 BEGIN 和 END 块可以包含要执行的命令分别在文件处理之前和之后。

这使得我们的扩展语法看起来像这样:

  1. awk 'BEGIN { action; }
  2. /search/ { action; }
  3. END { action; }' input_file

BEGIN 和 END 关键字是一组特定的条件,就像搜索参数一样。它们在处理文档之前和之后匹配。

这意味着您可以更改 BEGIN 部分中的一些内部变量。例如,/etc/passwd 文件是用冒号 (:) 而不是空格分隔的。

要打印出该文件的第一列,请执行以下命令:

  1. awk 'BEGIN { FS=":"; }
  2. { print $1; }' /etc/passwd
Output
root daemon bin sys sync games man . . .

您可以使用 BEGIN 和 END 块来打印有关您正在打印的字段的信息。使用以下命令将文件中的数据转换为表格,使用 使用制表符很好地隔开:

  1. awk 'BEGIN { FS=":"; print "User\t\tUID\t\tGID\t\tHome\t\tShell\n--------------"; }
  2. {print $1,"\t\t",$3,"\t\t",$4,"\t\t",$6,"\t\t",$7;}
  3. END { print "---------\nFile Complete" }' /etc/passwd

你会看到这个输出:

Output
User UID GID Home Shell -------------- root 0 0 /root /bin/bash daemon 1 1 /usr/sbin /bin/sh bin 2 2 /bin /bin/sh sys 3 3 /dev /bin/sh sync 4 65534 /bin /bin/sync . . . --------- File Complete

如您所见,您可以利用 awk 的一些功能很好地格式化内容。

每个扩展部分都是可选的。事实上,如果定义了另一个部分,则主要操作部分本身是可选的。例如,您可以执行以下操作:

  1. awk 'BEGIN { print "We can use awk like the echo command"; }'

你会看到这个输出:

Output
We can use awk like the echo command

现在让我们看看如何在输出的字段中查找文本。

字段搜索和复合表达式

在前面的一个示例中,您打印了 favorite_food.txt 文件中以 \sand 开头的行。这很容易,因为您要查找整行的开头。

如果您想知道搜索模式是否在 字段 的开头匹配怎么办?

创建一个新版本的 favorite_food.txt 文件,在每个人的食物前面添加一个项目编号:

  1. echo "1 carrot sandy
  2. 2 wasabi luke
  3. 3 sandwich brian
  4. 4 salad ryan
  5. 5 spaghetti jessica" > favorite_food.txt

如果你想从这个文件中找到所有以 \sa 开头的食物,你可以尝试这样开始:

  1. awk '/sa/' favorite_food.txt

这显示了所有包含 \sa 的行:

Output
1 carrot sandy 2 wasabi luke 3 sandwich brian 4 salad ryan

在这里,您正在匹配单词中任何 \sa 的实例。这最终包括诸如 \wasabi 之类的东西,它的模式在中间,或者 \sandy 不在你想要的列中。在这个如果您只对 second 列中以 \sa 开头的单词感兴趣。

您可以使用以下命令告诉 awk 仅匹配第二列的开头:

  1. awk '$2 ~ /^sa/' favorite_food.txt

如您所见,这允许我们仅在第二列的开头搜索匹配项。

field_num ~ 部分指定 awk 应该只关注第二列。

Output
3 sandwich brian 4 salad ryan

您可以通过包含 \! 轻松搜索不匹配的内容波浪号 (~) 之前的字符。此命令将返回所有不具有以 \sa 开头的食物的行:

  1. awk '$2 !~ /^sa/' favorite_food.txt
Output
1 carrot sandy 2 wasabi luke 5 spaghetti jessica

如果您稍后决定只对不以 \sa 开头且项目编号小于 5 的行感兴趣,则可以使用这样的复合表达式:

  1. awk '$2 !~ /^sa/ && $1 < 5' favorite_food.txt

这引入了一些新概念。第一个是使用 && 运算符为要匹配的行添加额外要求的能力。使用它,您可以组合任意数量的条件来匹配行。在本例中,您使用此运算符来添加检查第一列的值是否小于 5。

你会看到这个输出:

Output
1 carrot sandy 2 wasabi luke

您可以使用 awk 来处理文件,但您也可以使用其他程序的输出。

处理其他程序的输出

您可以使用 awk 命令来解析其他程序的输出,而不是指定文件名。例如,您可以使用 awk 从 ip 命令中解析出 IPv4 地址。

ip a 命令显示您机器上所有网络接口的 IP 地址、广播地址和其他信息。要显示名为 eth0 的接口的信息,请使用以下命令:

  1. ip a s eth0

您将看到以下结果:

Output
2571: eth0@if2572: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:0b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.11/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever

您可以使用 awk 来定位 inet 行,然后只打印出 IP 地址:

  1. ip a s eth0 | awk -F '[\/ ]+' '/inet / {print $3}'

-F 标志告诉 awk 使用正则表达式 [\/ ]+ 通过正斜杠或空格分隔。这会将行 inet 172.17.0.11/16 拆分为单独的字段。 IP 地址在第三个字段中,因为行首的空格也算作一个字段,因为您用空格和斜线分隔。请注意,在这种情况下,awk 将连续的空格视为单个空格。

输出显示 IP 地址:

Output
172.17.0.11

您会发现很多地方都可以使用 awk 来搜索或解析其他命令的输出。

结论

到目前为止,您应该基本了解如何使用 awk 命令来操作、格式化和有选择地打印文本文件和文本流。不过,Awk 是一个更大的主题,它实际上是一种完整的编程语言,包括变量赋值、控制结构、内置函数等。您可以在自己的脚本中使用它以可靠的方式格式化文本。

要了解有关 awk 的更多信息,您可以阅读其创建者的免费公共领域书籍,其中有更多详细信息。

©2015-2025 艾丽卡 support@alaica.com