Linux中的Awk命令示例

Awk是一种用于高级文本处理的通用脚本语言。 它主要用作报告和分析工具。

与大多数其他程序性编程语言不同,awk是数据驱动的,这意味着您定义了一组针对输入文本要执行的操作。 它获取输入数据,对其进行转换,然后将结果发送到标准输出。

本文介绍了awk编程语言的基本知识。 了解awk的基础知识将大大提高您在命令行上操作文本文件的能力。

怎么样 awk 作品#

awk有几种不同的实现。 我们将使用awk的GNU实现,称为gawk。 在大多数Linux系统上, awk 解释器只是一个符号链接 gawk

记录和字段

Awk可以处理文本数据文件和流。 输入数据分为记录和字段。 Awk一次对一条记录进行操作,直到达到输入结束为止。 记录由称为记录分隔符的字符分隔。 默认的记录分隔符是换行符,这意味着文本数据中的每一行都是一条记录。 可以使用 RS 变量。

记录包含由字段分隔符分隔的字段。 默认情况下,字段之间用空格分隔,包括一个或多个制表符,空格和换行符。

每个记录中的字段均以美元符号($),然后是字段编号,以1开头。第一个字段用表示 $1,第二个 $2, 等等。 最后一个字段也可以用特殊变量引用 $NF。 整个记录可以参考 $0

这是显示如何引用记录和字段的直观表示:

tmpfs      788M  1.8M  786M   1% /run/lock 
/dev/sda1  234G  191G   31G  87% /
|-------|  |--|  |--|   |--| |-| |--------| 
   $1       $2    $3     $4   $5  $6 ($NF) --> fields
|-----------------------------------------| 
                    $0                     --> record

AWK程式#

处理文本 awk,您编写了一个程序来告诉命令该做什么。 该程序由一系列规则和用户定义的功能组成。 每个规则包含一个模式和一个动作对。 规则由换行符或分号(;)。 通常,awk程序如下所示:

pattern { action }
pattern { action }
...

什么时候 awk 处理数据,如果模式与记录匹配,那么它将对该记录执行指定的操作。 当规则没有模式时,将匹配所有记录(行)。

awk操作包含在括号中({}),由语句组成。 每个语句指定要执行的操作。 一个动作可以包含多个语句,并用换行符或分号隔开(;)。 如果该规则无效,则默认为打印整个记录。

Awk支持不同类型的语句,包括表达式,条件,输入,输出语句等。 最常见的awk语句是:

  • exit -停止执行整个程序并退出。
  • next -停止处理当前记录,并移至输入数据中的下一个记录。
  • print -打印记录,字段,变量和自定义文本。
  • printf -使您可以更好地控制输出格式,类似于C和bash printf

编写awk程序时,井号后的所有内容 (#) 直到该行的末尾都被视为注释。 可以使用连字符反斜线()。

执行awk程序

awk程序可以通过多种方式运行。 如果程序简短而简单,则可以将其直接传递给 awk 命令行上的解释器:

awk 'program' input-file...

在命令行上运行程序时,应将其用单引号引起来(''),因此外壳程序不会解释程序。

如果程序很大且很复杂,最好将其放在文件中并使用 -f 将文件传递到的选项 awk 命令:

awk -f program-file input-file...

在下面的示例中,我们将使用一个名为“ teams.txt”的文件,该文件如下所示:

Bucks Milwaukee    60 22 0.732 
Raptors Toronto    58 24 0.707 
76ers Philadelphia 51 31 0.622
Celtics Boston     49 33 0.598
Pacers Indiana     48 34 0.585

Awk模式#

awk中的模式控制是否应该执行关联的动作。

Awk支持不同类型的模式,包括正则表达式,关系表达式,范围和特殊表达式模式。

当规则没有模式时,将匹配每个输入记录。 以下是仅包含操作的规则的示例:

awk '{ print $3 }' teams.txt

该程序将打印每个记录的第三个字段:

60
58
51
49
48

正则表达式模式

正则表达式或正则表达式是与一组字符串匹配的模式。 Awk正则表达式模式包含在斜杠(//):

/regex pattern/ { action }

最基本的示例是文字字符或字符串匹配。 例如,要显示每个包含“ 0.5”的记录的第一个字段,您可以运行以下命令:

awk '/0.5/ { print $1 }' teams.txt
Celtics
Pacers

模式可以是任何类型的扩展正则表达式。 这是一个示例,如果记录以两个或多个数字开头,则打印第一个字段:

awk '/^[0-9][0-9]/ { print $1 }' teams.txt
76ers

关系表达式模式

关系表达式模式通常用于匹配特定字段或变量的内容。

默认情况下,正则表达式模式与记录匹配。 要将正则表达式与某个字段进行匹配,请指定该字段并使用“包含”比较运算符(~)的模式。

例如,要打印第二条字段包含“ ia”的每条记录的第一字段,请输入:

awk '$2 ~ /ia/ { print $1 }' teams.txt
76ers
Pacers

要匹配不包含给定模式的字段,请使用 !~ 操作员:

awk '$2 !~ /ia/ { print $1 }' teams.txt
Bucks
Raptors
Celtics

您可以比较字符串或数字之间的关系,例如,大于,小于,等于等。 以下命令将打印所有第三字段大于50的记录的第一字段:

awk '$3 > 50 { print $1 }' teams.txt
Bucks
Raptors
76ers

范围模式

范围模式由用逗号分隔的两个模式组成:

pattern1, pattern2

从匹配第一个模式的记录开始的所有记录,直到匹配第二个模式的记录为止。

这是一个示例,它将打印所有记录的第一个字段,从包含“猛禽”的记录开始,直到包含“凯尔特人”的记录:

awk '/Raptors/,/Celtics/ { print $1 }' teams.txt
Raptors
76ers
Celtics

模式也可以是关系表达式。 下面的命令将打印所有记录,从第四个字段等于32的记录开始,直到第四个字段等于33的记录:

awk '$4 == 31, $4 == 33 { print $0 }' teams.txt
76ers Philadelphia 51 31 0.622
Celtics Boston     49 33 0.598

范围模式不能与其他模式表达式结合使用。

特殊表达方式

Awk包括以下特殊模式:

  • BEGIN -用于在处理记录之前执行操作。
  • END -用于在处理记录后执行操作。

BEGIN 模式通常用于设置变量, END 模式以处理记录等计算中的数据。

下面的示例将打印“开始处理”,然后打印每个记录的第三个字段,最后打印“结束处理”:

awk 'BEGIN { print "Start Processing." }; { print $3 }; END { print "End Processing." }' teams.txt
Start Processing
60
58
51
49
48
End Processing.

如果程序只有一个 BEGIN 模式,执行操作,并且不处理输入。 如果程序只有一个 END 模式,则在执行规则操作之前先处理输入。

GNU版本的awk还包括另外两个特殊模式 BEGINFILEENDFILE,可让您在处理文件时执行操作。

组合模式

Awk允许您使用逻辑AND运算符(&&)和逻辑或运算符(||)。

这是使用 && 运算符,以打印那些第三字段大于50且第四字段小于30的记录的第一字段:

awk '$3 > 50 && $4 < 30 { print $1 }' teams.txt
Bucks
Raptors

内置变量

Awk具有许多内置变量,这些变量包含有用的信息,并允许您控制程序的处理方式。 以下是一些最常见的内置变量:

  • NF -记录中的字段数。
  • NR -当前记录的编号。
  • FILENAME -当前正在处理的输入文件的名称。
  • FS -字段分隔符。
  • RS -记录分隔符。
  • OFS -输出字段分隔符。
  • ORS -输出记录分隔符。

这是显示如何打印文件名和行数(记录)的示例:

awk 'END { print "File", FILENAME, "contains", NR, "lines." }' teams.txt
File teams.txt contains 5 lines.

可以在程序的任何行中设置AWK中的变量。 要为整个程序定义变量,请将其放在 BEGIN 模式。

更改字段和记录分隔符

字段分隔符的默认值是任意数量的空格或制表符。 可以通过在 FS 变量。

例如,将字段分隔符设置为 . 您将使用:

awk 'BEGIN { FS = "." } { print $1 }' teams.txt
Bucks Milwaukee    60 22 0
Raptors Toronto    58 24 0
76ers Philadelphia 51 31 0
Celtics Boston     49 33 0
Pacers Indiana     48 34 0

字段分隔符也可以设置为多个字符:

awk 'BEGIN { FS = ".." } { print $1 }' teams.txt

在命令行上运行awk单行代码时,您还可以使用 -F 更改字段分隔符的选项:

awk -F "." '{ print $1 }' teams.txt

默认情况下,记录分隔符是换行符,可以使用 RS 变量。

这是显示如何将记录分隔符更改为的示例 .

awk 'BEGIN { RS = "." } { print $1 }' teams.txt
Bucks Milwaukee    60 22 0
732 
Raptors Toronto    58 24 0
707 
76ers Philadelphia 51 31 0
622
Celtics Boston     49 33 0
598
Pacers Indiana     48 34 0
585

Awk操作#

Awk动作用大括号括起来({}),并在模式匹配时执行。 一个动作可以有零个或多个语句。 多个语句按照它们出现的顺序执行,并且必须用换行符或分号(;)。

awk支持几种类型的动作语句:

  • 表达式,例如变量赋值,算术运算符,递增和递减运算符。
  • 控制语句,用于控制程序的流程(ifforwhileswitch, 和更多)
  • 输出语句,例如 printprintf
  • 复合语句,将其他语句分组。
  • 输入语句,以控制输入的处理。
  • 删除语句,删除数组元素。

print 语句可能是最常用的awk语句。 它打印文本,记录,字段和变量的格式化输出。

打印多个项目时,需要用逗号分隔。 这是一个例子:

awk '{ print $1, $3, $5 }' teams.txt

打印的项目用单个空格分隔:

Bucks 60 0.732
Raptors 58 0.707
76ers 51 0.622
Celtics 49 0.598
Pacers 48 0.585

如果您不使用逗号,则项目之间将没有空格:

awk '{ print $1 $3 $5 }' teams.txt

印刷品串联在一起:

Bucks600.732
Raptors580.707
76ers510.622
Celtics490.598
Pacers480.585

什么时候 print 用于不带参数的情况,默认为 print $0。 当前记录已打印。

要打印自定义文本,必须用双引号引起来的文本:

awk '{ print "The first field:", $1}' teams.txt
The first field: Bucks
The first field: Raptors
The first field: 76ers
The first field: Celtics
The first field: Pacers

您还可以打印特殊字符,例如换行符:

awk 'BEGIN { print "First linenSecond linenThird line" }'
First line
Second line
Third line

printf 语句使您可以更好地控制输出格式。 这是一个插入行号的示例:

awk '{ printf "%3d. %sn", NR, $0 }' teams.txt

printf 不会在每条记录之后创建换行符,因此我们正在使用 n

  1. Bucks Milwaukee    60 22 0.732 
  2. Raptors Toronto    58 24 0.707 
  3. 76ers Philadelphia 51 31 0.622
  4. Celtics Boston     49 33 0.598
  5. Pacers Indiana     48 34 0.585

以下命令计算每行第三字段中存储的值的总和:

awk '{ sum += $3 } END { printf "%dn", sum }' teams.txt
266

这是另一个示例,显示了如何使用表达式和控制语句来打印从1到5的数字平方:

awk 'BEGIN { i = 1; while (i < 6) { print "Square of", i, "is", i*i; ++i } }'
Square of 1 is 1
Square of 2 is 4
Square of 3 is 9
Square of 4 is 16
Square of 5 is 25

单行命令(如上面的命令)较难理解和维护。 编写更长的程序时,应创建一个单独的程序文件:

prg.awk

BEGIN { 
  i = 1
  while (i < 6) { 
    print "Square of", i, "is", i*i; 
    ++i 
  } 
}

通过将文件名传递给 awk 口译员:

awk -f prg.awk

您还可以通过使用shebang指令并将awk程序作为可执行文件运行,并将其设置为 awk 口译员:

prg.awk

#!/usr/bin/awk -f
BEGIN { 
  i = 1
  while (i < 6) { 
    print "Square of", i, "is", i*i; 
    ++i 
  } 
}

保存文件并使其可执行:

chmod +x prg.awk

现在,您可以通过输入以下内容来运行程序:

./prg.awk

在Awk程序中使用Shell变量

如果您使用的是 awk 在shell脚本中使用命令,则可能需要将shell变量传递给awk程序。 一种选择是用双引号而不是单引号将程序引起来,并在程序中替换变量。 但是,此选项会使awk程序更加复杂,因为您需要转义awk变量。

在awk程序中使用shell变量的推荐方法是将shell变量分配给awk变量。 这是一个例子:

num=51awk -v n="$num" 'BEGIN {print n}'
51

结论#

Awk是用于文本操作的最强大的工具之一。

本文勉强介绍了awk编程语言。 要了解有关awk的更多信息,请查阅Gawk官方文档。

如果您有任何疑问或反馈,请随时发表评论。

awk终端

Sidebar