【Bash百宝箱】awk

来源:互联网 发布:网络直播议论文 编辑:程序博客网 时间:2024/05/16 08:01

awk是一个强大的文本分析工具,从文件或管道中每次读取一行,默认以空格为分隔符把输入分割成若干字段,然后进行处理,一般格式如下:

awk [OPTIONS] 'patterns{actions}' files

分隔符

1、“-F value”设置每行文本的分隔符为value,默认是空格。文本行被分割后的各字段由数字来访问,从1开始,0表示整行文本。如下例子中的“print”是个命令,用于输出。

$ cat myfile 123 456 789abc:def:ghi$ awk '{print $1}' myfile 123abc:def:ghi$ awk -F : '{print $1}' myfile 123 456 789abc

从文件中读取参数

2、“-f file”从文件file中读取awk参数,可通过多个“-f”指定多个文件。

$ cat myfile 123 456 789abc:def:ghi$ cat myinput {print $1}$ awk -f myinput myfile 123abc:def:ghi

设置内建变量

3、“-v var=value”设置awk内建变量var的值为value。如下例子中的变量“RS”为输入分隔符,默认为“\n”。

$ cat myfile 123 456 789abc:def:ghi$ awk '{print $1}' myfile123abc:def:ghi$ awk -v RS='\n' '{print $1}' myfile123abc:def:ghi$ awk -v RS='5' '{print $1}' myfile1236

选项结束标记

4、“–”表示awk选项OPTIONS结束,其后若还有其它选项则出错。

$ cat myfile 123 456 789abc:def:ghi$ awk -F : '{print $1}' myfile 123 456 789abc$ awk -F : -- '{print $1}' myfile123 456 789abc

mawk扩展选项

5、“-W”是mawk提供的对awk的扩展选项,适用于awk,有如下6种。

-W version          输出版本号、版权和编译限制,简写为“-Wv”。-W dump            输出程序对应的汇编代码,简写为“-Wd”。-W interactive     简写为“-Wi”。-W exec file         从文件file中读取awk参数,简写为“-We file”。-W sprintf=num  设置sprintf的buffer长度。-W posix-space    强制mawk认为“\n”不是空格。

程序结构

6、awk程序是一系列的“patterns{actions}”组合,其中patterns表示以什么样的模式去匹配文本行,actions表示对匹配的文本行执行什么动作,两者可省其一,缺省patterns表示匹配所有行,缺省actions表示“{print}”。patterns可以是单个表达式或者逗号分隔的多个表达式,有两个特殊模式BEGIN、END,表示对第一行文本执行命令前、最后一行文本执行命令后所要执行的内容,因此这两者不能缺省actions。表达式以换行符或逗号分隔,长表达式可使用符号“\”进行续行,多个表达式可以放在一对花括号内为一组,符号“#”为注释符,支持“&&”和“||”以及如下语句。

if ( expr ) statementif ( expr ) statement else statementwhile ( expr ) statementdo statement while ( expr )for ( opt_expr ; opt_expr ; opt_expr ) statementfor ( var in array ) statementcontinuebreak

下面是一个简单的例子,文件myfile中有3行文本,每行文本以冒号分隔,共两个字段,分别表示单词字符数和单词,awk程序myinput用变量num统计所有的单词字符数,单词字符数大于5时打印当前文本行内容,命令“print”输出的内容无分隔符,逗号表示输出的内容以空格分隔。

$ cat myfile 5:apple4:pear6:banana$ cat myinputBEGIN {num=0}{    num+=$1    if ($1>5) print $0}END {print "total:",num}$ awk -F : -f myinput myfile 6:bananatotal: 15

awk语法与C类似,支持如下操作符:

              assignment          =  +=  -=  *=  /=  %=  ^=              conditional         ?  :              logical or          ||              logical and         &&              array membership    in              matching       ~   !~              relational          <  >   <=  >=  ==  !=              concatenation       (no explicit operator)              add ops             +  -              mul ops             *  /  %              unary               +  -              logical not         !              exponentiation      ^              inc and dec         ++ -- (both post and pre)              field               $

数据类型

7、awk中有两种基本数据类型,数字和字符串。数字可以是整数(-2)、小数(1.08)和科学计数(-1.1e4、.28E-3)。字符串放在双引号中,支持如下转义字符:

           \\        \            \"        "            \a        alert, ascii 7            \b        backspace, ascii 8            \t        tab, ascii 9            \n        newline, ascii 10            \v        vertical tab, ascii 11            \f        formfeed, ascii 12            \r        carriage return, ascii 13            \ddd      1, 2 or 3 octal digits for ascii ddd            \xhh      1 or 2 hex digits for ascii  hh

诸如“15”等可以被当作数字或字符串,awk会根据实际情况自动转换为合适的类型,如下例子中的格式化输出命令“printf”。

$ cat myfile 5:apple4:pear6:banana$ cat myinputBEGIN {num=0}{    num+=$1    if ($1>5) printf("%d\n", num)    if ($1>5) printf("%s\n", num)}END {print "total:",num}$ awk -F : -f myinput myfile1515total: 15

正则表达式

8、正则表达式放在两个斜线之间,格式如下:

expr ~ /r/expr !~ /r/

awk命令中如下两种正则形式是等效的:

/r/ { action }$0 ~ /r/ { action }

awk正则支持普通字符、转义字符和如下特殊符号:

^ $ . [ ] | ( ) * + ?

如下使用了正则的例子:

$ cat myfile 5:apple4:pear6:banana$ awk '/banana/' myfile 6:banana$ awk '!/banana/' myfile 5:apple4:pear

数组

9、awk支持数组,例子如下。

$ cat myfile 5:apple4:pear6:banana$ cat myinput {array[$1]=$2}END {for(var in array) print var,array[var]}$ awk -F : -f myinput myfile 4 pear5 apple6 banana

使用delete删除数组中的元素:

$ cat myfile 5:apple4:pear6:banana$ cat myinput {array[$1]=$2}END {delete array[5]; for(var in array) print var,array[var]}$ awk -F : -f myinput myfile 4 pear6 banana

内建变量

10、awk支持如下内建变量。

              ARGC      number of command line arguments.              ARGV      array of command line arguments, 0..ARGC-1.              CONVFMT   format for internal conversion of numbers  to  string, initially = "%.6g".              ENVIRON   array  indexed  by environment variables.  An environ‐ment string,      var=value is  stored  as ENVIRON[var]  = value.              FILENAME  name of the current input file.              FNR       current record number in FILENAME.              FS        splits records into fields as a regular expression.              NF        number of fields in the current record.              NR        current record number in the total input stream.              OFMT      format for printing numbers; initially = "%.6g".              OFS       inserted between fields on output, initially = " ".              ORS       terminates each record on output, initially = "\n".              RLENGTH   length  set by the last call to the built-in function, match().              RS        input record separator, initially = "\n".              RSTART    index set by the last call to match().              SUBSEP    used to build multiple array subscripts,  initially  = "\034".

访问内建变量不要使用美元符号,如下例子:

$ cat myfile hello sed5:apple4:pear6:banana$ awk -F : '{print ARGC}' myfile 2222$ awk -F : '{print ARGV[0],ARGV[1]}' myfile awk myfileawk myfileawk myfileawk myfile$ awk -F : '{print CONVFMT}' myfile %.6g%.6g%.6g%.6g$ awk -F : '{print FILENAME}' myfile myfilemyfilemyfilemyfile$ awk -F : '{print FNR}' myfile 1234$ awk -F : '{print FS}' myfile ::::$ awk -F : '{print NF}' myfile 1222$ awk -F : '{print NR}' myfile 1234$ awk -F : '{print OFMT}' myfile %.6g%.6g%.6g%.6g

内建函数

11、awk支持如下内建函数。

字符串处理函数——gsub(r,s,t)    把变量t中与正则r匹配的所有内容替换为字符串s,返回匹配的个数。gsub(r,s)    把当前行(即$0)中与正则r匹配的所有内容替换为字符串s,返回匹配的个数。index(s,t)    返回子串t在字符串s中的位置,从1开始。length(s)    返回字符串s的字符个数。match(s,r)    返回字符串s中与正则r第一个匹配的最长字符串的位置。split(s,A,r)r作为分隔符分割字符串s,结果保存到数组A中,返回分割的字段个数。split(s,A)    把内建变量FS的值作为分隔符分割字符串s,结果保存到数组A中,返回分割的字段个数。sprintf(format,expr-list)    返回格式化字符串。sub(r,s,t)gsub,但最多替换一次。sub(r,s)gsub,但最多替换一次。substr(s,i,n)    返回字符串s中从第i个字符开始的n个字符。substr(s,i)    返回字符串s中从第i个字符开始的剩余字符。tolower(s)    返回把字符串s转换成小写的结果。toupper(s)    返回把字符串s转换成大写的结果。数学函数——atan2(y,x)cos(x)exp(x)int(x)log(x)rand()sin(x)sqrt(x)srand(expr)  srand()

输入输出

12、awk输出使用print或格式化输出printf,printf用法类似于C/C++,输入使用getline,如下例子所示。

$ echo 123 | awk '{print $0}'123$ echo 123 | awk '{printf "%.10d\n", $0}'0000000123

getline每次多读取一行,可以覆盖当前行或者赋值给一个变量,多读取的行将不再被awk处理。

$ cat myfile 1awk12awk223awk3334awk44445awk55555$ awk '{print $0,NF,NR,FNR}' myfile 1awk1 1 1 12awk22 1 2 23awk333 1 3 34awk4444 1 4 45awk55555 1 5 5$ awk '{print $0,NF,NR,FNR,"====="; getline; print $0,NF,NR,FNR,"-----"}' myfile 1awk1 1 1 1 =====2awk22 1 2 2 -----3awk333 1 3 3 =====4awk4444 1 4 4 -----5awk55555 1 5 5 =====5awk55555 1 5 5 -----$ awk '{print $0,NF,NR,FNR,"====="; getline var; print $0,NF,NR,FNR,"-----"}' myfile 1awk1 1 1 1 =====1awk1 1 2 2 -----3awk333 1 3 3 =====3awk333 1 4 4 -----5awk55555 1 5 5 =====5awk55555 1 5 5 -----$ awk '{print $0,NF,NR,FNR,"====="; getline var; print var,NF,NR,FNR,"-----"}' myfile 1awk1 1 1 1 =====2awk22 1 2 2 -----3awk333 1 3 3 =====4awk4444 1 4 4 -----5awk55555 1 5 5 =====4awk4444 1 5 5 -----

自定义函数

13、awk支持自定义函数,一般格式如下:

function name( args ) { statements }

函数中的参数args以逗号分隔,包括输入参数和局部变量,输入参数与局部变量间一般额外地多个空格,可以使用return语句:

return opt_expr

下面例子中的getnumcount函数用于统计每行文本中的数字的个数,使用了内建函数length和substr以及正则匹配,最后打印数字的总个数,结果为9,是正确的。

$ cat myfile 1pear12apple223banana333$ cat myinput BEGIN {count=0}{count+=getnumcount($0)}END {print "total digit count:", count}function getnumcount(s,  n, t, i){    n = 0    t = length(s)    for(i = 1; i <=t; i++) if(substr(s,i,1) ~ /[0-9]/) n++    return n}$ awk -f myinput myfile total digit count: 9

完结~~

1 0
原创粉丝点击