如何在Linux上使用awk命令

时间:2020-01-09 10:39:53  来源:igfitidea点击:

在Linux上,awk是一种命令行文本处理发电机,也是一种功能强大的脚本语言。这是一些最酷功能的介绍。

awk的名称如何

" awk"命令是使用1977年写原始版本的三个人的姓名缩写来命名的:Alfred Aho,Peter Weinberger和Brian Kernighan。这三个人来自传说中的AT&T贝尔实验室Unix万神殿。

它是一种完整的脚本语言,以及用于命令行的完整文本操作工具包。如果本文引起胃口,我们可以查看有关awk及其功能的所有详细信息。

规则,模式和动作

" awk"在包含由模式和动作组成的规则的程序上工作。该操作在与模式匹配的文本上执行。模式包含在大括号({})中。模式和动作共同构成规则。整个awk程序都用单引号(')引起来。

让我们看一下" awk"程序的最简单类型。它没有模式,因此它匹配输入到其中的每一行文本。这意味着该动作在每一行上执行。我们将在who命令的输出中使用它。

这是who的标准输出:

who

也许我们不需要所有这些信息,而是只想查看帐户上的名称。我们可以将" who"的输出传递给" awk",然后告诉" awk"仅打印第一个字段。

默认情况下," awk"将字段视为由空格,行首或者行尾包围的字符串。字段由美元符号($)和数字标识。因此,$ 1代表第一个字段,我们将在printaction中使用它来打印第一个字段。

我们输入以下内容:

who | awk '{print }'

awk打印第一个字段,并丢弃其余行。

我们可以根据需要打印任意多个字段。如果我们添加逗号作为分隔符,awk将在每个字段之间打印一个空格。

我们键入以下内容以同时打印此人登录的时间(第四栏):

who | awk '{print ,}'

有几个特殊的字段标识符。这些代表整个文本行和文本行中的最后一个字段:

  • $ 0:代表整行文本。

  • $ 1:代表第一个字段。

  • $ 2:代表第二个字段。

  • $ 7:代表第七字段

  • $ 45:代表第45个字段。

  • $ NF:代表字段数,代表最后一个字段。

我们将键入以下内容以打开一个小型文本文件,该文件包含归因于Dennis Ritchie的短引号:

cat dennis_ritchie.txt

我们希望awk可以打印报价的第一,第二和最后一个字段。请注意,尽管它被软件包在终端窗口中,但仅是一行文本。

我们输入以下命令:

awk '{print ,,$NF}' dennis_ritchie.txt

我们不知道这种简单性。是文本行中的第18个字段,我们不在乎。我们所知道的是这是最后一个字段,我们可以使用$ NF来获取其值。句点仅被视为字段正文中的另一个字符。

添加输出字段分隔符

我们还可以告诉awk在字段之间打印特定字符,而不是默认的空格字符。 date命令的默认输出有些奇怪,因为时间恰好在中间。但是,我们可以键入以下内容并使用awk提取所需的字段:

date
date | awk '{print ,,}'

我们将使用OFS(输出字段分隔符)变量在月,日和年之间放置分隔符。请注意,下面我们将命令用单引号(')而不是大括号({})括起来:

date | awk 'OFS="/" {print,,}'
date | awk 'OFS="-" {print,,}'

BEGIN和END规则

在开始任何文本处理之前,将执行一次" BEGIN"规则。实际上,它是在awk甚至读取任何文本之前执行的。在所有处理完成后执行END规则。我们可以有多个BEGINEND规则,它们将按顺序执行。

对于我们的" BEGIN"规则的示例,我们将打印先前使用的" dennis_ritchie.txt"文件中的所有引号,并在其上方加上标题。

为此,我们键入以下命令:

awk 'BEGIN {print "Dennis Ritchie"} {print 
who | awk 'BEGIN {print "Active Sessions"} {print ,}'
}' dennis_ritchie.txt

请注意," BEGIN"规则在其自己的花括号(" {}")集中包含其自己的动作集。

我们可以使用与之前使用的命令相同的技术,将命令从" who"输出到" awk"。为此,我们键入以下内容:

awk -F: '{print ,}' /etc/passwd

输入场分隔符

如果我们希望awk处理不使用空格分隔字段的文本,则必须告诉它文本将哪个字符用作字段分隔符。例如,/ etc / passwd文件使用冒号()分隔字段。

我们将使用该文件和-F(分隔符字符串)选项来告诉awk将冒号()用作分隔符。我们输入以下内容告诉awk打印用户帐户和主文件夹的名称:

awk -F: ' >= 1000 {print ,}' /etc/passwd

输出包含用户帐户的名称(或者应用程序或者守护程序名称)和主文件夹(或者应用程序的位置)。

添加图案

如果我们只对普通用户帐户感兴趣,则可以在打印操作中包含一个模式,以过滤掉所有其他条目。因为用户ID号等于或者大于1,000,所以我们可以基于该信息进行过滤。

仅当第三个字段($ 3)的值等于或者大于1,000时,我们才键入以下内容来执行打印操作:

awk -F: 'BEGIN {print "User Accounts\n-------------"}  >= 1000 {print ,}' /etc/passwd

该模式应紧接与其关联的动作之前。

我们可以使用BEGIN规则为我们的小报告提供标题。我们使用(\ n)符号键入以下内容,以在标题字符串中插入换行符:

awk '/UUID/ {print 
awk '/^UUID/ {print 
awk '/^UUID/ {print }' /etc/fstab
}' /etc/fstab
}' /etc/fstab

模式是成熟的正则表达式,它们是" awk"的荣耀之一。

假设我们要查看已挂载文件系统的通用唯一标识符(UUID)。如果我们在/ etc / fstab文件中搜索字符串UUID的出现,它应该为我们返回该信息。

我们在命令中使用搜索模式/ UUID /:

awk 'BEGIN { print sqrt(625)}'

它查找所有出现的UUID并打印这些行。实际上,如果没有" print"动作,我们将得到相同的结果,因为默认动作会打印整个文本行。但是,为了清楚起见,明确表示通常很有用。浏览脚本或者历史记录文件时,我们会为自己留下的线索感到高兴。

找到的第一行是注释行,尽管UUID字符串其中,但" awk"仍然找到了它。我们可以调整正则表达式,并告诉awk只处理以UUID开头的行。为此,我们键入以下内容,其中包括行标记的开始(^):

awk 'BEGIN {print atan2(0, -1)}'

那更好!现在,我们只看到真正的安装说明。为了进一步优化输出,我们键入以下内容,并将显示限制在第一个字段:

awk 'BEGIN {print atan2(0, -1)*100}'

如果我们在这台机器上安装了多个文件系统,我们将得到一个整齐的表,列出它们的UUID。

内建功能

awk具有许多功能,我们可以从命令行和脚本中调用和使用自己的程序。如果我们进行一些挖掘,将会发现它非常富有成果。

为了演示调用函数的一般技术,我们将看一些数字函数。例如,以下显示了625的平方根:

awk 'BEGIN { print sqrt((2+3)*5)}'

此命令显示反正切为0(零)和-1(正好是数学常数pi):

#!/usr/bin/awk -f

BEGIN {
  # set the input and output field separators
  FS=":"
  OFS=":"
  # zero the accounts counter
  accounts=0
}
{
  # set field 2 to nothing
  =""
  # print the entire line
  print 
chmod +x omit.awk
# count another account accounts++ } END { # print the results print accounts " accounts.\n" }

在以下命令中,我们在打印前修改atan2()函数的结果:

./omit.awk /etc/passwd

函数可以接受表达式作为参数。例如,这是一种要求25的平方根的复杂方法:

##代码##

awk脚本

如果命令行变得复杂,或者我们开发了要再次使用的例程,则可以将" awk"命令转移到脚本中。

在示例脚本中,我们将执行以下所有操作:

  • 告诉shell程序使用哪个可执行文件来运行脚本。

  • 准备awk以使用FS字段分隔符变量来读取带有由冒号()分隔的字段的输入文本。

  • 使用OFS输出字段分隔符来告诉awk使用冒号(:)分隔输出中的字段。

  • 将计数器设置为0(零)。

  • 将每行文本的第二个字段设置为空白值(始终为x,因此我们无需查看它)。

  • 打印带有修改后的第二个字段的行。

  • 递增计数器。

  • 打印计数器的值。

我们的脚本如下所示。

"开始"规则执行准备步骤,而"结束"规则显示计数器值。中间规则(没有名称,也没有模式,因此它与每行匹配)修改第二个字段,打印该行,并增加计数器。

脚本的第一行告诉shell程序使用哪个可执行文件(在我们的示例中为" awk")来运行脚本。它还将-f(文件名)选项传递给awk,它通知它要处理的文本将来自文件。运行时,我们会将文件名传递给脚本。

我们将以下脚本作为文本包含在内,因此我们可以剪切和粘贴:

##代码##

将其保存在名为" omit.awk"的文件中。为了使脚本可执行,我们使用chmod键入以下内容:

##代码##

现在,我们将运行它,并将/ etc / passwd文件传递给脚本。这是文件" awk"将使用脚本中的规则为我们处理的:

##代码##

处理文件并显示每一行,如下所示。

第二个字段中的x条目已删除,但请注意,字段分隔符仍然存在。对行进行计数,总数在输出的底部给出。