awk使用方法笔记

来源:互联网 发布:h5微信支付 java 编辑:程序博客网 时间:2024/05/21 14:45
1. awk最基本的功能是在输入文件中按行匹配指定的字符串格式,如果匹配则将当前行复制到缓冲区进行进一步处理,但并不改变输入文件本身。awk匹配每一行(称为Record)后,使用默认或指定的分割符自动将其分割为若干段(称为Field),每一段可使用$number进行引用和访问。其中段号0对应整个Record的内容。处理完成每一行后继续读入下一行进行处理。

awk命令的一般格式为

awk‘/pattern/ {action} /pattern1/{action1}’   datafile1 datafile2

awk可以同时指定多个匹配条件和处理动作(规则),每条规则之间可以另起新行分割,只要将它们包含在同一单引号里面即可。awk可以同时处理多个文件对象。

如果省略{action},则awk默认打印所有匹配pattern的行。如果想要指定不作任何事情,怎可省略action的同时,只保留{}


2. 有三种方法运行awk程序。

  • awk‘program’ datafile1 datafile2 …

    这里的programpatternaction的组合,方式如前述。

  • awk–f program-file datafile1 datafile2 …

    适用于程序较为复杂的情形。将/pattern/{action}组合放入program-file(不需要加单引号)后即可调用。为了使程序文件一目了然,可使用后缀名.awk

  • awk程序写为脚本文件后执行。

    在脚本文件行首加上 #!/bin/awk –f,然后BEGIN{}块指定主程序执行的先决条件,中间是主程序,最后是END{}块指定结束操作。运行时,按脚本方式运行,并在后面指定输入文件。

需要注意的是,awk脚本和shell脚本中执行awk语句是不同的,前者使用awk程序的语法规则;后者只是将前两种用法写入文件执行,遵从shell脚本的语法规则。


3.读入文件时,除了使用默认的方式按行读入Record,也可以指定其它的Record Separator

awk ‘BEGIN {RS = “/”}; {print $0}’ datafile

使用awk内置变量RS指定新的Record分割符为/。因为awk打印时在每一条Record后重起新行,这样通过指定新的分割符,就为datafile添加了新的换行。特别地,若指定RS为空字符,则以空行为分割符。awk利用内置变量FNR追踪当前读入的行号(记录号)。每次读入新文件时,FNR将自动置为0。另外一个变量NR记录当前awk命令一共读入了的行数(记录数),该变量从0开始,但即使读入新文件也不会重新置0。如果在主程序中重新设定了RS,则只会影响设定后读入的内容。


4.对于读入的每一行(记录),awk默认以(一个或多个)空格/制表符为分段符将其划分为若干段(Field),每一段可使用$number进行引用和访问,其中number可以是可计算数值的变量或表达式。$0对应整条记录,$NF对应最后一个分段。如果记录号大于总分段数,则返回空字符,但可以对其进行赋值操作后打印。注意,不带$NF对应一个内置变量,它的值是当前记录的分段数量。例如:

awk ‘$1 ~ /pattern/ {print $!, $NF} ’ datafile

上例中打印datafile中所有行中首个分段包含pattern的行的第一个分段和最后一个分段。~是匹配运算符,它检验给定字符串($1)是否匹配之后的正则表达式。
除了默认的分割符,awk允许指定字符或正则表达式作为分割符。分割符不出现在分段中。awk使用内置变量FS指定段分割符。

awk ‘BEGIN {FS = “:”}; {print $0}’ datafile

使用命令行指定分割符时,可使用参数–F

awk –F, ‘/pattern/{action}’ datafile

上例指定“,为段分隔符。


5. 使用print打印多个分段时,默认以空白作为间隔符,但也可以使用内置变量OFSoutput fieldseparator)显式指定其它间隔符。类似的多个记录之间也可以指定默认的换行符之外的其它字符串。

awk  ‘BEGIN {OFS = “;”; ORS=“\n\n”; OFMT = “%d” }             {print $1, $2}’ datafile

除了OFS,本例中ORS是记录之间的间隔符。

OFMT则是处理数字时的打印格式。但实际上,我们通常用printf来格式化打印内容。它可以为每一个分段指定宽度,指定数字的打印格式(基数、指数形式等等)。用法如下:

awk  ‘{print format item1, item2…}’

print不同,printf不会在打印完一条记录后自动添加换行,并且OFSORS将失去其作用。format的指定方式和C语言中printf函数的format用法相同。

awk  ‘{printf  “%-10s   %s\n”,  $1, $2}’    datafile

本例中,将分段1打印为最小宽度为10个字符的字符串,若不够则在左边补足空白符(不带-时在右边补足空白符)。然后空格后直接打印分段2。最后插入换行符后继续处理下一条记录。
另外,还可以利用 >, >>|操作符重定向printprintf的输出。例如:

awk ‘{ print $1 > “output_file_name”printf format $2 | “sort –r >> output_file_name_1”}’ datafile


6. pattern 支持正则表达式匹配。


7.awkaction必须被{}包括,各个不同的action之间以换行或者分号分隔。

awk中,使用+进行的加法运算,自动将字符串转换为整型。如若在字符串中遇到非数字字符,则将其及后面的所有字符作为0加到前面的数值中。连接字符串或连接数字和字符串时,只需将字符串变量写在一起,并用括号括起来即可。例如:

awk  ‘BEGIN{a=100; b=“10test10”; print(a+b);}’   awk ‘BEGIN{ a=100; b=“10test10”;print(a b)}’

第一条命令将打印110,第二条命令将打印10010test10。此外awk提供内置变量CONVFMT定义浮点数(整数转字符串时不受影响)转换为字符串时的格式规则。对变量进行转字符串操作后,浮点数不会按照CONVFMT定义的精度重新赋值,而是保持原来的值。例如:

awk  ‘BEGIN{a=123.321; CONVFMT = “%3.1f”;print a “ is a number”print a+1.654}’   
第一行输出是123.3 is anumber,第二行输出是124.975

另需注意的是,字符串的下标从1开始,例如函数index(“peanut”, “an”) 将返回3,如果index没有在源字符串中找到目标,则返回0


8. awk支持内建函数和自定义函数的调用,支持if- else if -else条件语句,for, while/do while等循环语句,breakcontinue等循环控制语句,以及nextexit等流程控制语句。

C语言不同,awk中可以使用for( index in array )的形式遍历数组下标(idnex),然后使用array[index]访问数组中相应的元素。next语句使程序跳过当前读入的记录,立即进行读入处理下一条记录的操作,它不能出现在BEGINEND块儿中。exit使程序立即退出awkexit默认返回0(执行成功),但也可以在其后加上返回值来表示其它返回状态。


9.声明awk数组时,无需声明其长度,且类似于javascript编程语言,任何数字和字符串都能作为数组下标使用。awk数组元素是关联关系(associative),下标和元素值对应,但下标之间并无直接关系。建立或访问数组元素时通过array_name[index] (=value)方式,删除数组元素时使用delete array_name[index]语句。


10.awk内建了一些常用的函数,int(var),sqrt(var), exp(x), log(x), sin(x), cos(x), atan2(var1, var2), rand() srand(var)等数值计算函数;index(srch_src,srch), length(str), match(str, regexp), split(str, array, fieldsep), sprint(format,expression1…), sub(regexp, replacement, target), gsub(regexp, replaecement,target), substr(str, start, length), tolower(str), toupper(str)等字符串操作函数。


11. 除了管道输入、标准输入流和文件流,awk还提供内置函数getline支持输入控制。如果getline成功读入下一条记录,则返回1;如果getline遇到文件结束标志则返回0;如果读入下一条记录中出错,则返回-1getline读入时不受匹配条件(pattern)的影响。

不带参数的getline直接在程序块继续读入当前输入文件的下一行,并将其分段等待其他处理。它将改变$0,NF, FNR, NRRT的值。

getline var将一条记录读入到变量var中,但不会将其分段,因此只有NRFNR将会变化,而$0NF将仍是上一条记录的内容。主程序体执行完成后,awk跳过var对应的记录行,读入其下一行。

getline < “filename”从文件名为filename的另一个文件读入一行,并将其分段,但不对当前文件流作其它改变,因此NRFNR不会变化,而$0NF将根据从filename中读入的记录行改变。主程序体执行完成后,awk读入当前文件的下一行继续处理。

getline var< “filename”从文件名为filename的另一个文件读入一条记录到变量var中,只改变内置变量RT

command |getline的形式,command将作为命令运行,命令输出作为getline的输入,每次读入一行,并遍历所有行。该命令会改变$0,NFRT的值。

“command” | getline var的形式,command将作为命令运行,命令输出作为getline的输入,每次读入一行,并遍历所有行。

使用getline读取其它文件内容时,必须注意关闭文件流。

close(filename)close(command)

如果不关闭,那么下次使用getline读相同的文件时,不会从最开始行读,而是会接着上一次getline的行的后面开始读入。

0 0
原创粉丝点击