在Linux命令中,awk命令常用于处理文本内容。下面举例介绍awk命令的常用用法。GNUgawkawk既是一种命令又是一种编程语言,它可以有不同的实现版本。在Linux系统上,awk的实现是GNUgawk。在shell中执行awk命令实际上执行的是gawk命令。如下:$ls-l/usr/bin/awklrwxrwxrwx1rootroot21Feb12019/usr/bin/awk->/etc/alternatives/awk$ls-l/etc/alternatives/awklrwxrwxrwx1rootroot13March8,2019/etc/alternatives/awk->/usr/bin/gawk$ls-l/usr/bin/gawk-rwxr-xr-x1rootroot441512July3,2013/usr/bin/gawk可以查看所以,/usr/bin/awk文件最终链接到/usr/bin/gawk文件,而/usr/bin/gawk文件没有链接到其他文件。在以下描述中,如无特殊说明,awk均指代GNUgawk。awk的命令格式,查看manawk的说明,也链接到mangawk的内容。阐明。下面引用的内容就出自这个在线帮助手册,其中对awk的基础介绍如下:awk的基本功能是在文件中搜索包含特定模式的行(或其他文本单元)。当一行与其中一种模式匹配时,awk在该行执行指定的操作。awk继续以这种方式处理输入行,直到它到达输入文件的末尾。awk命令的基本使用方法说明如下:有几种方法可以运行awk程序。如果程序很短,最简单的方法是将其包含在运行awk的命令中,如下所示:awk'program'input-file1input-file2...其中程序由一系列模式和操作组成,awk程序如下所示:pattern{action}当程序很长时,通常把它放在一个文件中,然后用这样的命令运行它会更方便:awk-fprogram-fileinput-file1input-file2...program两边有单引号所以shell不会将任何awk字符解释为特殊的shell字符。引号还导致shell处理所有program作为awk的单个参数,并允许程序超过一行。您也可以在没有任何输入文件的情况下运行awk。如果您键入以下命令行:awk'program'awk将程序应用于标准输入,这通常意味着您在键盘上键入的任何内容。也就是说,awk命令在给定文件中查找包含特定模式的行,并对它找到的行执行一些特定的操作,如程序参数所指定的那样。如上所述,给定的程序参数应该用单引号括起来,以防止shell扩展一些特殊字符。如果没有提供文件名,awk命令默认读取标准输入。如果未提供特定模式,则默认处理所有行。注意:awk命令的程序参数后面的参数会被认为是文件名,即使参数值被引号括起来,它仍然会被认为是文件名,而不是字符串。此命令无法处理命令行参数提供的字符串值。具体例子如下:$cattestawkThisisateststring.ThisisanotherTESTstring.$awk'{print$3}'testawkaanother$awk'{print$3}'"testawk"aanother$awk'{print$3}'“这是一个测试字符串。”awk:致命:无法打开文件“这是一个测试字符串。”forreading(Nosuchfileordirectory)可以看出,awk'{print$3}'testawk命令打印出testawk文件的第三列。awk'{print$3}'"testawk"命令也打印出testawk文件的第三列。即使testawk被双引号括起来,也不意味着打印了“testawk”字符串的第三列。awk'{print$3}'“这是一个测试字符串。”命令会执行出错,提示名为Thisisateststring的文件。找不到,它不会处理“Thisisateststring”这个字符。而不是字符串本身的内容,而是把字符串当成一个文件名,需要处理对应文件的内容。如果确实需要使用awk命令处理字符串,可以使用管道符|连接标准输入。例如,使用echo命令打印一个字符串的值,然后通过管道运算符将这个值传递给awk命令的标准输入。具体例子如下:$echo"Thisisateststring."|awk'{print$4}'test$value="这是一个新的测试字符串。"$echo"$value"|awk'{print$4}'new可以看到echo"Thisisateststring."|awk'{print$4}'命令首先通过echo输出字符串的值,然后通过管道符|将这个输出连接到awk命令的标准输入,就可以处理这个字符串而不会报错。回显“$值”|awk'{print$4}'命令打印出value变量值第四列的内容,可以用来处理变量值。注意:管道运算符|这里使用的是连接标准输入,让awk命令可以处理传递给标准输入的字符串,但是使用重定向标准输入操作符<不允许awk命令处理字符串。重定向是基于文件的操作,给定的字符串将被视为文件名,例如:$awk'{print$4}'<"Thisisateststring."-bash:Thisisateststring.:没有这个文件或目录,可以看到“Thisisateststring”。重定向标准输入操作符<右边的字符串被认为是文件名,bash提示找不到文件。这不是awk命令报错,而是bash在处理重定向时报错。在awk程序中使用awk命令的关键在于如何编写程序参数。查看GNUgawk在线帮助手册的描述。部分内容如下:awk中的程序由模式-动作对组成。没有模式的动作总是运行。awk程序通常如下所示:[pattern]{action}awk中的模式控制规则的执行--当其模式匹配当前输入记录时执行规则。该操作的目的是告诉awk在找到模式匹配项后要做什么。一个动作由一个或多个awk语句组成,用大括号('{...}')括起来。即awk命令的程序参数由pattern和action组成。Pattern用于指定匹配模式,对匹配到的行执行后面的action操作,不匹配的行不做处理。Action用于指定对匹配的行进行什么样的操作,这些操作语句应该包含在大括号{}中。如果未提供模式参数,则默认处理所有行。一些模式参数的写法如下:/regularexpression/一个正则表达式。当输入记录的文本符合正则表达式时匹配。表达式单个表达式。当其值为非零(如果是数字)或非空(如果是字符串)时匹配。具体例子如下:$awk'/a.*/{print$0}'testawk这是一个测试字符串。这是另一个测试字符串。$awk'/test/{print$0}'testawk这是一个测试字符串。$awk'test{print$0}'testawk$awk'"NONE"{print$0}'testawk这是一个测试字符串。这是另一个测试字符串。$awk'$3=="another"{print$0}'testawk这是另一个测试字符串。可以看到,awk'/a.*/{print$0}'testawk命令使用a.*正则表达式来匹配包含字符'a'的行,然后打印出整行。awk'/test/{print$0}'testawk命令打印包含字符串“test”的行。awk'test{print$0}'testawk命令不打印任何内容,这并不意味着打印包含字符串“test”的行。awk'"NONE"{print$0}'testawk命令打印出testawk文件的所有行,即使该文件不包含“NONE”字符串。根据上面的描述,给定的模式参数是一个用双引号括起来的非空字符串,表示它总是匹配的,不管字符串的内容是什么。awk'$3=="another"{print$0}'testawk命令匹配第三列包含字符串“another”的行并打印出整行。即如果要指定匹配某个字符串,把pattern参数写成“/regularexpression/”就比较简单了。写成“表达式”,需要了解awk的表达式写法。获取给定行的内容awk在读取每一行的内容时,会根据拆分字符将行内容拆分为多个单词。可以使用$number获取number列的单词,number的值从1开始。比如$1对应第一列的单词,$2对应第二列的单词,$3对应第三列中的单词,依此类推。您可以使用$NF获取拆分后最后一列的内容。特别是,$0获取整行,包括行首或行尾的任何空格。以“Thisisateststring”这一行为例。举个例子,对应关系如下:$1This$2的写法对应的值为$3a$4test$5string.$NFstring.$0Thisisateststring。使用-F选项指定Splitcharacters前面提到,awk默认使用空格将行内容分割成多个单词。如果要根据其他字符进行分割,可以使用-F选项指定分割字符。GNUgawk在线帮助手册对-F选项的解释如下:-Ffs--field-separatorfs将FS变量设置为fs。比如像“clang/utils/analyzer/”这样的目录路径,如果想根据/来拆分得到各个目录名,可以使用-F选项指定拆分字符为/。具体例子如下:$echo"clang/utils/analyzer/"|awk-F'/''{print$1,$2}'clangutils$echo"clang/utils/analyzer/"|awk-F'/''{print"Lastwordis:"$NF}'Lastwordis:可以看到使用-F'/'指定分割字符后,给定的内容会被/分割,并且拆分词不包含'/'字符。由于给定内容的最后一个字符是'/',最后一列拆分的内容为空,所以$NF的内容为空。当需要根据特定字符拆分行内容时,使用awk命令特别有用。-F选项可以指定分割字符,然后用$number获取数字列的内容,方便处理。打印语句前面的例子都使用了打印语句来打印内容。GNUgawk联机帮助手册对print语句的解释如下:使用print语句生成具有简单、标准化格式的输出。您可以在以逗号分隔的列表中仅指定要打印的字符串或数字。它们被输出,由单个空格分隔,后跟一个换行符。该语句如下所示:printitem1,item2,…可以选择将整个项目列表括在括号中。没有项目的简单语句“print”等同于“print$0”:它打印整个当前记录。即print语句打印给定字符串或数字的内容,不同的内容要用逗号','隔开,但打印出来的效果是用空格隔开。经测试,如果用其他字符隔开是不行的,打印出来的内容会连在一起。具体例子如下:$awk'/test/{print$3,$5}'testawkastring.$awk'/test/{print$3$5}'testawkastring.$awk'/test/{print$3_$5}'测试串。可以看出,$3和$5在print之后写的时候,打印出来的两个字符串是用空格隔开的,而写成$3$5或者$3_$5的时候,打印出来的两个字符串是直接连在一起的,没有打印出所有给定的空格,或者下划线'_'。也就是说,它们只能用逗号分隔。如果print后不带参数,默认相当于print$0,会打印整行。如果不提供action参数,连花括号{}都不提供,默认相当于{print$0}。如果只提供大括号{}并且大括号内没有内容,则它是空操作,什么都不做。具体例子如下:$awk'/test/{print}'testawk这是一个测试字符串。$awk'/test/'testawk这是一个测试字符串。$awk'/test/{}'testawk可以看到,awk'/test/{print}'testawk命令在print之后提供参数来打印出整行。awk'/test/'testawk命令不提供动作参数,它也打印出整行。awk'/test/{}'testawk命令提供了一个操作参数,它只是没有指定要做什么并且什么也不打印。
