如何在Linux上使用awk命令
在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
代表第一个字段,我们将在print
action中使用它来打印第一个字段。
我们输入以下内容:
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
规则。我们可以有多个BEGIN
和END
规则,它们将按顺序执行。
对于我们的" BEGIN"规则的示例,我们将打印先前使用的" dennis_ritchie.txt"文件中的所有引号,并在其上方加上标题。
为此,我们键入以下命令:
awk 'BEGIN {print "Dennis Ritchie"} {printwho | 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/ {printawk '/^UUID/ {print}' /etc/fstabawk '/^UUID/ {print }' /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 printchmod +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条目已删除,但请注意,字段分隔符仍然存在。对行进行计数,总数在输出的底部给出。