awk 命令本质上是一种脚本语言,也是 Linux 中强大的文本操作工具。 它以其创始人阿尔弗雷德的名字命名 一个嘿,彼得 宽艾因伯格和布莱恩 钾埃尔尼安。 Awk 很受欢迎,因为它能够像处理数字一样轻松地处理文本(字符串)。
它逐行扫描输入行或记录的序列,搜索与模式匹配的行。 当找到匹配项时,可以执行操作。 它是一种模式-动作语言。
awk 的输入可以来自文件、重定向和管道,也可以直接来自标准输入。
术语
在深入学习本教程之前,让我们先了解一些基本术语。 这将使您更容易更好地理解这个概念。
1. 记录
awk 将每一行视为一条记录。
- RS 用于提及记录分隔符。 默认情况下,RS 设置为换行符。
- 不 是跟踪记录号的变量。 它的值等于正在处理的记录。 NR 可以假设为默认场景中的行号。
2. 字段
每条记录都分为多个字段。 这意味着每一行都被分成多个字段。
- FS 是字段分隔符。 默认情况下,FS 设置为空白。 这意味着每个单词都是一个字段。
- NF 是特定记录中的字段数。
字段编号为:
- 整行 0 美元。
- 第一个字段 $1。
- $2 用于第二个字段。
- $n 用于第 n 个字段。
- $NF 用于最后一个字段。
- $NF-1 用于倒数第二个字段。
awk 的标准格式
awk 命令的标准格式为:
$ awk ' BIGIN{/instructions/} /pattern/ {ACTIONS} END{/instructions}' file_name
- 模式-动作对将括在单引号(‘)中
- BEGIN 和 END 是可选的,用于提及在处理输入之前和之后要执行的操作。
- 该模式表示如果满足将导致执行操作的条件
- 该操作指定匹配成功时要执行的精确命令集。
- 如果输入来自文件,则要指定 file_name。
awk 命令的基本用法
awk 可用于根据文本中的某种模式将消息打印到终端。 如果您运行 awk 命令而没有任何模式并且只有一个打印命令,则每次按 Enter 时 awk 都会打印消息。 发生这种情况是因为 awk 命令需要来自命令行界面的输入。
$ awk '{print "This is how awk command is used for printing"}'
使用 awk 处理来自命令行的输入
我们在前面的例子中看到,如果没有提到输入源,那么 awk 只是从命令行获取输入。
awk 下的输入被视为记录的集合,而每条记录又是字段的集合。 我们可以使用它来实时处理输入。
$ awk '$3=="linux" {print "That is amazing!", $1}'
此代码查找该行中的第三个单词是“linux”的模式。 当找到匹配项时,它会打印消息。 这里我们引用了同一行的第一个字段。 在继续之前,让我们创建一个文本文件以用作输入。
这可以在 Linux 中使用 cat 命令来完成。
该文件的文本是:
First 200 Second 300 Third 150 Fourth 300 Fifth 250 Sixth 500 Seventh 100 Eight 50 Ninth 70 Tenth 270
这些可能是名为 First、Second 的不同客户的卢比会费……依此类推。
使用字段从文件打印
可以使用 awk 打印来自文件的输入。 我们可以参考不同的字段以花哨的方式打印输出。
$ awk '{print $1, "owes", $2}' rec.txt
$1 和 $2 分别用于引用字段一和字段二。 这些在我们的输入文件中是每行的第一个和第二个单词。 我们没有在这个命令中提到任何模式,因此 awk 命令对每条记录运行操作。 awk 的默认模式是“”,它匹配每一行。
使用 awk 分隔符
awk 中有三种类型的分隔符。
- OFS:输出字段分隔符
- FS:字段分隔符
- RS:记录分隔符
1.输出字段分隔符(OFS)
您可以注意到,默认情况下,打印命令用空格分隔输出字段。 这可以通过更改 OFS 来更改。
$ awk 'OFS=" owes " {print $1,$2}' rec.txt
实现了与前一种情况相同的输出。 默认输出字段分隔符已从空白更改为“欠”。 然而,这并不是更改 OFS 的最佳方式。 应该在 awk 命令的 BEGIN 部分更改所有分隔符。
2. 字段分隔符 (FS)
可以通过更改 FS 的值来更改字段分隔符。 默认情况下,FS 设置为空白。 我们使用以下数据创建了另一个文件。 此处名称和金额以“-”分隔
First-200 Second-300 Third-150 Fourth-300 Fifth-250 Sixth-500 Seventh-100 Eight-50 Ninth-70 Tenth-270
$ awk 'FS="-" {print $1}' rec-sep.txt
您可以注意到输出的第一行是错误的。 似乎第一条记录 awk 无法分隔字段。 这是因为我们在操作部分提到了更改字段分隔符的语句。 操作部分的第一次运行是在处理完第一条记录之后。 在这种情况下,First-200 被读取和处理,字段分隔符作为空格。
正确做法:
$ awk 'BEGIN {FS="-"} {print $1}' rec_1.txt
现在我们得到了正确的输出。 第一条记录分离成功。 放置在 BEGIN 部分的任何语句在处理输入之前运行。 BEGIN 部分最常用于在处理输入之前打印消息。
3. 记录分隔符 (RS)
第三种分隔符是记录分隔符。 默认情况下,记录分隔符设置为换行符。 可以通过更改 RS 的值来更改记录分隔符。 如果输入是 CSV(逗号分隔值)文件,则更改 RS 很有用。
例如,如果输入是:
First-200,Second-300,Third-150,Fourth-300,Fifth-250,Sixth-500,Seventh-100,Eight-50,Ninth-70,Tenth-270
这是与上面相同的输入,但采用逗号分隔的格式。
我们可以通过更改 RS 字段来处理这样的文件。
$ awk 'BEGIN {FS="-"; RS=","; OFS=" owes Rs. "} {print $1,$2}' rec_2.txt
awk 中的布尔运算
布尔运算可以用作模式。 可以使用不同的字段值进行比较。 awk 的工作方式类似于 if-then 命令。 在我们的数据中,我们可以找到超过卢比的客户。 200 到期。
$ awk '$2>200 {print $1, "owes Rs.",$2}' rec.txt
这通过将每个记录的第二个字段与 200 进行比较并打印条件是否为真来为我们提供列表。
使用 awk 命令匹配字符串文字
由于 awk 与字段一起工作,我们可以将其用于我们的利益。 运行 ls -l 命令会给出当前目录中所有文件的列表以及附加信息。
awk 命令可以与 ls -l 一起使用以找出在 5 月份创建的文件。 $6 是用于显示文件创建月份的字段。 我们可以使用它并将字段与字符串“May”匹配。
$ ls -l | awk '$6=="May" {print $9}'
awk 中的用户定义变量
为了执行额外的操作,可以在 awk 中定义变量。 例如,要计算会费大于 200 的人员列表中的总和,我们可以定义一个 sum 变量来计算总和。
$ awk 'BEGIN {sum=0} $2>200 {sum=sum+$2; print $1} END{print sum}' rec.txt
sum 变量在 BEGIN 部分初始化,在 action 部分更新,并在 END 部分打印。 仅当模式部分中提到的条件为真时,才会使用操作部分。 由于每行都会检查模式,因此该结构作为一个循环工作,每次满足条件时都会执行更新。
使用 awk 命令计数
awk 命令还可以用来统计行数、单词数,甚至字符数。 让我们从使用 awk 命令计算行数开始。
计算行数
可以通过在 END 部分打印出 NR 变量来打印行数。 NR 用于存储当前记录号。 由于在处理完所有记录后访问 END 部分,因此 END 部分中的 NR 将包含记录总数。
$ awk 'END { print NR }' rec.txt
计算字数
要获得单词数,可以使用 NF。 NF 是每条记录中的字段数。 如果将所有记录的 NF 相加,则可以达到单词数。 命令中,c是用来统计单词数的。 对于每一行,该行中的字段总数添加到 c。 在 END 部分,打印 c 将给出总字数。
$ awk 'BEGIN {c=0} {c=c+NF} END{print c}' rec.txt
计算字符数
每行的字符数可以通过使用 awk 的内置长度函数获得。 $0 用于获取整个记录。 length($0) 将给出该记录中的字符数。
awk '{ print "number of characters in line", NR,"=" length($0) }' rec.txt
结论
awk 命令可用于执行非常强大的文本操作。 直接访问字段的便利性使 awk 比 sed 更具优势。 如前所述,awk 不仅是一种命令行工具,而且还是一种强大的脚本语言。 要了解有关 awk 的更多信息,请参阅此内容。