`

AWK介绍

 
阅读更多

1.awk简介

  1. awk以记录和字段的方式来查看文本文件

  2. 和其他编程语言一样,awk包含变量、条件和循环

  3. awk能够进行运算和字符串操作

  4. awk能够生成格式化的报表数据

 

2.awk概述

awk程序awk命令、括在括号(或写在文件)中的程序指令以及输入文件的文件名几个部分组成。如果没有输入文件,输入则来自于标准输入。

awk指令由模式、操作或者模式与操作的组合组成。模式是由某种类型的表达式组成的语句。如果某个表达式中没有出现关键在if,但实际在计算时却暗含if这个词,那么这个表达式就是模式。操作由括在大括号中的一条或多条语句组成,语句之间用分号或者换行符隔开。模式不能括在大括号中,模式由包括在两个正斜杠之间的正则表达式、一个或多个awk操作符组成的表达式组成。

格式:

awk '/search pattern1/ {Actions}

/search pattern2/ {Actions}' file

 

3.工作原理

  1. awk使用一行作为输入(通过文件或者管道),并将这一行赋给内部变量$0

  2. 行被空格分解为字段(单词),每一个字段存储在已编号的变量中,从$1开始。(awk的内部变量FS用来确定字段的分隔符。初始时,为空格,包含制表符和空格符)

  3. 对于一行,按照给定的正则表达式的顺序进行匹配,如果匹配则执行对应的Action,如果没有匹配上则不执行任何动作 ,Search PatternAction是可选的,但是必须提供其中一个 。如果Search Pattern未提供,则对所有的输入行执行Action操作。如果Action未提供,则默认打印出该行的数据 。{}这种Action不做任何事情,和未提供的Action的工作方式不一样

  4. 打印字段,用printprintfsprintf,格式:{ print $1, $3 }内部变量output field separatorOFS),默认为空格,$n之间的逗号被OFS中的字符替换。

  5. 输出之后,从文件中另取一行,并将其复制到$0中,覆盖原来的内容。重复进行……

 

4.格式化输出

print函数

print函数用于打印不需要特别编排格式的简单输出。更为复杂的格式编排则要使用printfsprintf。若懂得C语言,则也一定懂得如何使用printfsprintf

 

print函数的的转义序列

/b 退格

/f 换页

/n 换行

/r 回车

/t 制表符

/047 八进制值47,即单引号

/c c代表任意其他字符

打印数字时,可能需要控制数字的格式。可以通过printf来实现,但是通过设置一个特殊的变量OFMT,是用print函数也可以控制数字打印格式。OFMT默认为“%.6gd”,表示只打印小数部分的前6位。

1

long@long-Ubuntu:~$ awk 'BEGIN { OFMT="%.2f"; print 1.2456789, 12E-2 }'

1.25 0.12

 

printf函数

printf函数返回一个带格式的字符串给标准输出,如同C语言中的printf语句。printf语句包括一个加引号的控制串,控制串中可能嵌套有若干格式说明和修饰符。控制串后面跟逗号,之后是一列由逗号分隔的表达式。与print函数不同的是,printf函数不会在行尾自动换行。若要换行,在控制串中提供转义字符/n。每个百分号和格式说明都必须有一个对应的变量。要打印百分号就必须在控制串中给出两个百分号。

 

printf函数的转义字符

c 字符

s 字符串

d 十进制整数

ld 十进制长整数

u 十进制无符号整数

lu 十进制无符号长整数

x 十六进制整数

lx 十六进制长整数

o 八进制整数

lo 八进制长整数

e 用科学计数法表示浮点数

f 浮点数

g 选用ef中较短的一种形式

 

printf函数的修饰符

- 左对齐修饰符

# 显示八进制整数时,前面加 0 ,显示十六进制整数时,前面加 0x

+ 显示使用 d 、 e 、 f 、 g 转换的整数时,加上正负号

0 用 0 而不是空白符来填充所显示的值

 

printf函数控制串里的管道符(竖杠)是文本的一部分,用于指示格式的起始与结束。

2

long@long-Ubuntu:~$ echo "UNIX" | awk ' { printf "|%-15s|/n", $1 }'

|UNIX |

long@long-Ubuntu:~$ echo "UNIX" | awk ' { printf "|%15s|/n", $1 }'

| UNIX|

%15s表示占15个字符的字符串)

 

5.文件中的awk命令

如果awk命令写在文件里,用-f选项制定awk的文件名,后面加上要处理的输入文件的文件名。awk从缓冲区读入一条指令,接着测试awk文件中的每一条命令,然后对读入的记录执行命令。

3

long@long-Ubuntu:~$ cat employees

Tom Jones 4424 5/12/66 543354

Mary Adams 5346 11/4/63 28765

Sally Chang 1654 7/22/54 650000

Billy Black 1683 9/23/44 336500

long@long-Ubuntu:~$ cat awkfile

/^Mary/ {print "Hello Mary!"}

{print $1, $2, $3}

long@long-Ubuntu:~$ awk -f awkfile employees

Tom Jones 4424

Hello Mary!

Mary Adams 5346

Sally Chang 1654

 

6.记录与字段

awk看来,输入数据具有格式和结构。默认情况下,每一行称为一条记录,以换行符结束。

默认情况下,输入和输出记录的分隔符(行分隔符)都是回车符(换行符),分别保存在awk的内置变量ORSRS中,其值可以修改,只能以特定方式进行修改。

每条记录的记录号都保存在awk的内置变量NR中,每处理完一条记录,NR的值加1

 

每条记录由字段(field)组成,用空白符(空格或制表符)分隔。内置变量NF保存记录的字符数。前面提到的FS,用来分隔字段,并且删除各字段前多余的空白或制表符。可以在BEGIN语句中或命令行上赋值来改变FS的值。也可以在命令行上通过-F选项来改变FS的值。

4

long@long-Ubuntu:~$ cat employees2

Tom Jones:4424:5/12/66:543354

Mary Adams:5346:11/4/63:28765

Sally Chang:1654:7/22/54:650000

Billy Black:1683:9/23/44:336500

long@long-Ubuntu:~$ awk -F: '/Tom Jones/{print $1,$2}' employees2

Tom Jones 4424

 

也可以使用多个字段分隔符。此时FS对应的是一个正则表达式字符串,被括在方括号中。

5

long@long-Ubuntu:~$ awk -F'[ :/t]' '{print $1,$2}' employees

Tom Jones

Mary Adams

Sally Chang

Billy Black

long@long-Ubuntu:~$ awk -F'[ :/t]' '{print $1,$2}' employees2

Tom Jones

Mary Adams

Sally Chang

Billy Black

 

前面提到的输出字段分隔符OFS,输出时如果没有用逗号来分隔字段,结果中字段将堆在一起。OFS的值也可以改变。

 

7.模式与操作

模式由正则表达式、判别条件真伪的表达式或者二者的组合构成。awk默认打印所有是表达式结果为真的文本行。模式表达式中暗含着if语句,如此,就不必用花括号将它括起来。当if是显式给出时,这个表达式就成了操作语句,语法将不一样

操作是花括号中以分号分隔的语句。若操作前有模式,则该模式控制执行操作的时机。

 

正则表达式

/取消字符的特殊含义

^在行首匹配。^不能用于匹配嵌套在一个字符串中的行首,if ("line1/nLINE 2" ~ /^L/) ...不为真。

$在行尾匹配。$不能用于匹配嵌套在一个字符串中的行尾,if ("line1/nLINE 2" ~ /1$/) ...不为真

.匹配单个任意字符,包括换行符。

[...]匹配制定字符组中的任意一个。

[^ …]匹配任何一个不在制定字符组中的字符

|匹配|两侧的任意的字符(组),在所有的正则表达式中优先级最低。The alternation applies to the largest possible regexps on either side.

(...) Parentheses are used for grouping in regular expressions, as in arithmetic. They can be used to concatenate regular expressions containing the alternation operator.

*匹配零个或者多个前导字符

+匹配一个或者多个前导字符

?匹配零个或者多个前导字符

{n} ,{n,} ,{n,m} One or two numbers inside braces denote an interval expression. If there is one number in the braces, the preceding regexp is repeated n times. If there are two numbers separated by a comma, the preceding regexp is repeated n to m times. If there is one number followed by a comma, then the preceding regexp is repeated at least n times:

wh{3}y

Matches ‘whhhy’, but not ‘why’ or ‘whhhhy’.

wh{3,5}y

Matches ‘whhhy’, ‘whhhhy’, or ‘whhhhhy’, only.

wh{2,}y

Matches ‘whhy’ or ‘whhhy’, and so on.

 

Interval expressions were not traditionally available in awk. They were added as part of the POSIX standard to make awk and egrep consistent with each other.

However, because old programs may use ‘{’ and ‘}’ in regexp constants, by default gawk does not match interval expressions in regexps. If either --posix or --re-interval are specified, then interval expressions are allowed in regexps.

For new programs that use ‘{’ and ‘}’ in regexp constants, it is good practice to always escape them with a backslash. Then the regexp constants are valid and work the way you want them to.

正则表达式中 ‘*’,,‘+’, ‘?’以及‘{’和 ‘}’有最高的优先级,解析来是连接操作符,最后是‘|’.算术中一样,括号可以用来改变顺序。

POSIX awkgawk中,如果正则表达式里'*''+''?'前面没有任何字符,那么这三个字符代表他们自己。很多其他版本的awk中,将把这视为错误。

gawk-Specific Regexp Operators

/Y匹配一个单词开头或者末尾的空字符串。

/B匹配单词内的空字符串。

/<匹配一个单词的开头的空字符串,锚定开始。

/>匹配一个单词的末尾的空字符串,锚定末尾。

/w匹配一个字母数字组成的单词。

/W匹配一个非字母数字组成的单词。

/‘匹配字符串开头的一个空字符串。

/'匹配字符串末尾的一个空字符串。

 

The various command-line options control howgawkinterprets characters in regexps:

Nooptions :

In the default case, gawk provides all the facilities of POSIX regexps and the previously described GNU regexp operators. GNU regexp operators described in Regexp Operators. However, interval expressions are not supported.

--posix :

Only POSIX regexps are supported; the GNU operators are not special (e.g., ‘/w’ matches a literal ‘w’). Interval expressions are allowed.

--traditional :

Traditional Unix awk regexps are matched. The GNU operators are not special, interval expressions are not available, nor are the POSIX character classes ([[:alnum:]], etc.). Characters described by octal and hexadecimal escape sequences are treated literally, even if they represent regexp metacharacters. Also, gawk silently skips directories named on the command line.

--re-interval :

Allow interval expressions in regexps, even if --traditional has been provided. (--posix automatically enables interval expressions, so --re-interval is redundant when --posix is is used.)

 

POSIX增加的括号字符类

Class Meaning

[:alnum:] Alphanumeric characters.

[:alpha:] Alphabetic characters.

[:blank:] Space and TAB characters.

[:cntrl:] Control characters.

[:digit:] Numeric characters.

[:graph:] Characters that are both printable and visible.

[:lower:] Lowercase alphabetic characters.

[:print:] Printable characters (characters that are not control characters).

[:punct:] Punctuation characters

[:space:] Space characters (such as space, TAB, and formfeed, to name a few).

[:upper:] Uppercase alphabetic characters.

[:xdigit:] Characters that are hexadecimal digits.

 

9.范围模板

范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现之间所有行。如果有一个模板没出现,则匹配到开头或末尾。如$ awk '/root/,/mysql/' test将显示root第一次出现到mysql一次出现之间的所有行。

 

10.关系运算符

<<===!=>=>~!~(最后两个表示匹配和不匹配正则表达式)

 

11.条件表达式

条件表达式1 ?条件表达式2 :条件表达式3

 

12.算术运算

可以在模式中进行计算,awk都将按浮点方式执行运算。支持:+-*/%^(幂)

 

13.逻辑操作符与复合模式

&&||,!

 

6一个验证passwd文件有效性的例子

long@long-Ubuntu:~$ cat /etc/passwd | awk -F: '/

> NF != 7 {/

> printf("line %d, does not have 7 fields:%s/n",NR,$0)}/

> $1 !~ /[A-Za-z0-9]/{printf("line %d, non alpha and numeric user id:%d: %s/n",NR,$0)}/

> $2 == "*" {printf("line %d, no password: %s/n", NR,$0)}'

 

1 cat把结果输出给awkawk把域之间的分隔符设为冒号。

2如果域的数量(NF)不等于7,就执行下面的程序。

3 printf打印字符串"line ?? does not have 7 fields",并显示该条记录。

4若第一个域没包含任何字母和数字,printf打印“no alpha and numeric user id",并显示记录数和记录。

5如果第二个域是一个星号,就打印字符串“no passwd”,紧跟着显示记录数和记录本身。

 

7:几个示例:

$ awk '/^(no|so)/' filename-----打印所有以模式noso开头的行。

$ awk '/^[ns]/{print $1}' filename-----如果记录以ns开头,就打印这个记录。

$ awk '$1 ~/[0-9][0-9]$/(print $1}' filename-----如果第一个域以两个数字结束就打印这个记录。

$ awk '$1 == 100 || $2 < 50' filename-----如果第一个或等于100或者第二个域小于50,则打印该行。

$ awk '$1 != 10' filename-----如果第一个域不等于10就打印该行。

$ awk '/test/{print $1 + 10}' filename-----如果记录包含正则表达式test,则第一个域加10并打印

$ awk '{print ($1 > 5 ? "ok "$1: "error"$1)}' filename—---如果第一个域大于5则打印问号后面的表达式值,否则打印冒号后面的表达式值。

$ awk '/^root/,/^mysql/' filename----打印从以正则表达式root开头的记录到以正则表达式mysql开头的记录范围内的所有记录。如果找到一个新的正则表达式root开头的记录,则继续打印直到下一个以正则表达式mysql开头的记录为止,或到文件末尾。

 

14.变量

awk中,变量不需要定义就可以直接使用,变量类型可以是数字或字符串,由awk根据上下文推导,不用指定

变量名可以包括字母、数字和下划线,但不能以数字开头。

赋值格式:Variable = expression

变量被设置后,就变成与等号右边那个表达式相同的类型。

未经初始化的变量的值是0或者“”,具体是哪个取决于它们被使用时的上下文。

将一个字符串强制转换为数字,方法为:name+0

将数字转换成字符串的方法是:number “”

赋值运算符:=+=-=*=/=%=^=

递增递减运算符,也分为前置和后置两种,遵循的规则与C语言中一样

 

awk可以在命令行中给变量赋值,然后将这个变量传输给awk脚本。如$ awk -F: -f awkscript month=4 year=2004 filename,上式的monthyear都是自定义变量,分别被赋值为42004。在awk脚本中,这些变量使用起来就象是在脚本中建立的一样。注意,如果命令行中filename的位置在变量之前,那么在BEGIN语句中的变量就不能被使用(参见后面的BEGIN模式)。

-v选项,awk-v选项允许在BEGIN语句中,处理命令行变量。从命令行传递的每一个变量前面都必须加-v选项

 

字段变量也可被赋值和修改。新的字段可以通过赋值来创建。字段变量引用的字段如果没有值,则被赋值为空串(即如果只有4个字段,但是对$6复制,那么不存在的$5被赋值为空串)。字段的值发生变化时,awk会以OFS的值作为字段间隔符重新计算$0的值。字段数目通常在100以内。如$ awk '{$2 = 100 + $1; print }' test,上式表示,如果第二个域不存在,awk将计算表达式100$1的值,并将其赋值给$2,如果第二个域存在,则用表达式的值覆盖$2原来的值。

 

内建变量

$n当前记录的第n个字段,字段间由FS分隔。

$0完整的输入记录。

ARGC命令行参数的数目。

ARGIND命令行中当前文件的位置(0开始算)

ARGV包含命令行参数的数组。

CONVFMT数字转换格式(默认值为%.6g)

ENVIRON环境变量关联数组。

ERRNO最后一个系统错误的描述。

FIELDWIDTHS字段宽度列表(用空格键分隔)

FILENAME当前文件名。

FNRNR,但相对于当前文件。

FS字段分隔符(默认是任何空格)

IGNORECASE如果为真(即非0值),则进行忽略大小写的匹配。

NF当前记录中的字段数。

NR当前记录数。

OFMT数字的输出格式(默认值是%.6g)

OFS输出字段分隔符(默认值是一个空格)

ORS输出记录分隔符(默认值是一个换行符)

RLENGTHmatch函数所匹配的字符串的长度。

RS记录分隔符(默认是一个换行符)

RSTARTmatch函数所匹配的字符串的第一个位置。

SUBSEP数组下标分隔符(默认值是/034)

 

15.BEGIN模式

BEGIN模式后面跟一个操作块。awk必须在对输入文件进行任何处理之前,先执行该操作块。常被用于修改内置变量的值,为用户自定义变量赋初值和打印输出的页眉或者标题。。

8

$ awk 'BEGIN{FS=":"; OFS="/t"; ORS="/n/n"}{print $1,$2,$3} filename。上式表示,在处理输入文件以前,域分隔符(FS)被设为冒号,输出文件分隔符(OFS)被设置为制表符,输出记录分隔符(ORS)被设置为两个换行符。$ awk 'BEGIN{print "TITLE TEST"}只打印标题。

 

编写awk脚本时,可以先测试好BEGIN块操作,再写程序的其他部分。

 

16.END模式

END模式不匹配任何输入行,而是执行任何与之关联的操作。Awk处理完所有输入行之后才处理END模式。

9

$ awk 'END{print "The number of records is" NR}' test,上式将打印所有被处理的记录数。

 

17.重定向和管道

awk可使用shell的重定向符进行重定向输出

输入重定向需用到getline函数。getline从标准输入、管道或者当前正在处理的文件之外的其他输入文件获得输入。它负责从输入获得下一行的内容,并给NF,NRFNR等内建变量赋值。如果得到一条记录,getline函数返回1,如果到达文件的末尾就返回0,如果出现错误,例如打开文件失败,就返回-1

10

$ awk 'BEGIN{ "date" | getline d; print d}' filename

执行linuxdate命令,并通过管道输出给getline,然后再把输出赋值给自定义变量d,并打印它。

$ awk 'BEGIN{"date" | getline d; split(d,mon); print mon[2]}' filename

执行shelldate命令,并通过管道输出给getline,然后getline从管道中读取并将输入赋值给dsplit数把变量d转化成数组mon,然后打印数组mon的第二个元素。

$ awk 'BEGIN{while( "ls" | getline) print}'

命令ls的输出传递给getline作为输入,循环使getlinels的输出中读取一行,并把它打印到屏幕。这里没有输入文件,因为BEGIN块在打开输入文件前执行,所以可以忽略输入文件。

$ awk 'BEGIN{while (getline < "/etc/passwd" > 0) lc++; print lc}'

awk将逐行读取文件/etc/passwd的内容,在到达文件末尾前,计数器lc一直增加,当到末尾时,打印lc的值。注意,如果文件不存在,getline返回-1,如果到达文件的末尾就返回0,如果读到一行,就返回1,所以命令while (getline < "/etc/passwd")在文件不存在的情况下将陷入无限循环,因为返回-1表示逻辑真。

 

如果在awk程序中打开了管道,就必须先关闭它才能打开另一个管道。管道符右边的命令被括在双引号之间。每次只能打开一个管道。如果打算再次在awk程序中使用某个文件或管道进行读写,则可能要先关闭程序,因为其中的管道会保持打开状态直至脚本运行结束。注意:管道一旦被打开,就会保持打开状态直至awk退出。END块中的语句也会受到管道影响。通过close()可关闭管道

11

(脚本)

{ print $1,$2,$3 | “sort -r +1 -2 +0 -1” }

END{

close(“sort -r +1 -2 +0 -1”)

<rest of statements> }

 

awk内置函数systemLinux系统命令作为参数,执行该命令并将命令的退出状态返回给awk程序。作为参数的命令必须加双引号。

 

18.条件语句

awk条件语句源于C语言,可以用他们对包含判断语句的程序进行控制。

if语句

格式: {if (expression){

statement; statement; ...

}

}

12

$ awk '{if ($1 <$2) print $2 "too high"}' test

如果第一个域小于第二个域则打印。

$ awk '{if ($1 < $2) {count++; print "ok"}}' test

如果第一个域小于第二个域,则count1,并打印ok

 

if/else语句

格式:{if (expression){

statement; statement; ...

}

else{

statement; statement; ...

}

}

13

$ awk '{if ($1 > 100) print $1 "bad" ; else print "ok"}' test

如果$1100则打印$1 bad,否则打印ok

$ awk '{if ($1 > 100){ count++; print $1} else {count--; print $2}' test

如果$1大于100,则count加一,并打印$1,否则count减一,并打印$1

 

if/else else if语句

格式:{if (expression){

statement; statement; ...

}

else if (expression){

statement; statement; ...

}

else if (expression){

statement; statement; ...

}

else {

statement; statement; ...

}

}

 

19.循环语句

常常用来对记录中的每个字段重复执行某些操作,或者在END块中用来循环处理某个数组中的所有元素。三种类型的循环:while循环,for循环,特殊for循环

while循环

第一步给一个变量赋初值,在while中测试该变量,若值为真(非0),则进入循环执行语句。do while循环与while类似,唯一的区别是do while至少执行一次循环体,然后才测试表达式。

14

$ awk '{ i = 1; while ( i <= NF ) { print NF,$i; i++}}' test

变量的初始值为1,若i小于可等于NF(记录中域的个数),则执行打印语句,且i增加1。直到i的值大于NF.

 

for循环

for循环的圆括号中需要3个表达式,前两个分别是初始化和测试表达式,第3个用于更新测试表达式所用的变量。注意,for循环中,第一条语句只能初始化一个变量(这与C语言不同)

15

$ awk '{for (i = 1; i<NF; i++) print NF,$i}' test。作用同上。

 

循环控制

break语句用于在满足条件的情况下跳出循环

continue语句用于在满足条件的情况下忽略后面的语句,直接返回循环的顶端。

16

1. {for ( x=3; x<=NF; x++)

if ($x<0){print "Bottomed out!"; break}}

2. {for ( x=3; x<=NF; x++)

if ($x==0){print "Get next item"; continue}}

 

20.程序控制语句

next语句,从输入文件中取出下一行输入,然后从awk脚本的顶部重新开始执行。

exit语句,用于终止awk程序。它只能中断对记录的处理,不能跳过END语句。若exit语句的参数是一个0~255之间的值,这个值会被打印在命令行上,以表明程序是否执行成功,并指出失败类型。

 

21.数组

数组在awk中被称为关联数组associative arrays),其下表既可以是字符串也可以是数字。数组的键和值都存储在awk程序内部的一个表中,该表采用的是散列算法,所以数组元素不是顺序存储的。数组也是被用到时才被创建。awk还能判定数组用于保存数字还是字符串,根据上下文被初始化为0或者空字符串。数组大小不需要声明。

用变量作为数组下标。

17

$ awk {name[x++]=$2};END{for(i=0;i<NR;i++) print i,name[i]}' test

数组name中的下标是一个自定义变量xawk初始化x的值为0,在每次使用后增加1。第二个域的值被赋给name数组的各个元素。在END模块中,for循环被用于循环整个数组,从下标为0的元素开始,打印那些存储在数组中的值。因为下标是关健字,所以它不一定从0开始,可以从任何值开始。

 

特殊for循环

当下标为字符串或者非连续的数字时,不能用for循环来遍历数组。这是就要使用特殊的for循环。

格式:foritem in arrayname) {

print arrayname[item]

}

}

 

用字符串作为数组下标

数组下表可以由包含单个字符或字符串的变量组成,如果是字符串,就必须用双引号括起来。

 

用字段的值作为数组下标

18

long@long-Ubuntu:~$ cat datafile1

4234 Tom 43

4567 Arch 45

2008 Eliza 65

4571 Tom 22

3298 Eliza 21

4622 Tom 53

2345 Mary 24

long@long-Ubuntu:~$ awk '{count[$2]++}END{for(name in count)print name, / count[name]}' dataf ile1

Arch 1

Tom 3

Eliza 2

Mary 1

统计文件中某个字段出现的次数

 

数组与函数

awk的内置函数split能够将字符串拆分为词,然后保存在数组中。

格式:split(字符串,数组,字段分隔符)

split(字符串,数组)

awk的内置函数delete用于删除数组元素

 

多维数组

awk定义多为数组的方法是把多个下标串成字符串,下标之间用内置变量SUBSEP的值分隔。变量SUBSEP的值默认为“/034”,这是个不可打印的字符,不太可能用作下标中的字符。

19

long@long-Ubuntu:~$ cat datafile2

1 2 3 4 5

2 3 4 5 6

3 4 5 6 7

6 7 8 9 10

long@long-Ubuntu:~$ awk '{nf=NF

for(x=1; x<=NF; x++){

matrix[NR,x] = $x

}

}END{

for(x=1;x<=NR;x++){

for(y=1;y<=nf;y++)

printf "%d/t", matrix[x,y]

printf "/n"

}

}' datafile2

1 2 3 4 5

2 3 4 5 6

3 4 5 6 7

6 7 8 9 10

 

22.处理命令行参数

awk可以从内置数组ARGV中得到命令行参数,其中包括命令awk。但所有传递给awk的选项不再其中。ARGV数组下标从0开始。ARGC是一个包含命令行参数个数的内置变量。

 

23.awk的内置函数

字符串函数

sub函数匹配记录中最大、最靠左边的子字符串的正则表达式,并用替换字符串替换这些字符串。如果没有指定目标字符串就默认使用整个记录。替换只发生在第一次匹配的时候。

格式:sub (regular expression, substitution string):

sub (regular expression, substitution string, target string)

20

$ awk '{ sub(/test/, "mytest"); print }' testfile

$ awk '{ sub(/test/, "mytest"); $1}; print }' testfile

第一个例子在整个记录中匹配,替换只发生在第一次匹配发生的时候

第二个例子在整个记录的第一个域中进行匹配,替换只发生在第一次匹配发生的时候。

gsub函数作用如sub,但它在整个文档中进行匹配。

格式:gsub (regular expression, substitution string)

gsub (regular expression, substitution string, target string)

 

index函数返回子字符串第一次被匹配的位置,偏移量从位置1开始。

格式:index(string, substring)

 

length函数返回记录的字符数,若未指定参数,则length函数返回记录中的字符个数

格式:length( string )

length

 

substr函数返回从字符串指定位置开始的子字符串,如果指定长度超过实际长度,就返回其实际内容。

格式:substr( string, starting position )

substr( string, starting position,子串长度)

 

match函数返回在字符串中正则表达式位置的索引,如果找不到指定的正则表达式则返回0match函数把内置变量RSTART设为子串在字符串中的起始位置,RLENGTH为则设为子串的长度。这些变量可以被substr函数用来提取相应模式的子串。

格式:match( string, regular expression )

21

$ awk '{start=match("this is a test",/[a-z]+$/); print start}' filename

$ awk '{start=match("this is a test",/[a-z]+$/); print start, RSTART, RLENGTH }'/ filename

第一个实例打印以连续小写字符结尾的开始位置,这里是11

第二个实例还打印RSTARTRLENGTH变量,这里是11(start)11(RSTART)4(RLENGTH)

 

touppertolower函数可用于字符串大小间的转换,该功能只在gawk中有效。

格式:toupper( string )

tolower( string )

 

split函数可按给定的分隔符把字符串分割为一个数组。如果分隔符没提供,则按当前FS值进行分割。

格式:split( string, array, field separator )

split( string, array )

22

$ awk '{ split( "20:18:00", time, ":" ); print time[2] }' filename

把时间按冒号分割到time数组内,并显示第二个数组元素18

 

sprintf函数返回一个指定格式的表达式。可以在sprintf函数中使用printf函数的格式规范

格式:variable=sprintf(“含有格式说明的字符串”,表达式1,表达式2..,表达式n)

 

 

内置算术函数

int(x)

returns nearest integer to x, located between x and zero and truncated toward zero.

sqrt(x)

returns the positive square root of x. gawk reports an error if x is negative.

exp(x)

returns the exponential of x (e ^ x) or reports an error if x is out of range.

log(x)

returns the natural logarithm of x, if x is positive; otherwise, it reports an error.

sin(x)

returns the sine of x, with x in radians.

cos(x)

returns the cosine of x, with x in radians.

atan2(y, x)

returns the arctangent of y / x in radians.

rand()

returns a random numberuniformly distributed between zero and one0<=value<1

srandx)

functionsrandsets the seed, for generating random numbers to the value x

 

时间函数

systime函数返回从197011日开始到当前时间(不计闰年)的整秒数。

格式:systime()

 

strftime函数使用C库中的strftime函数格式化时间。

日期和时间格式说明符

格式描述

%a 星期几的缩写(Sun)

%A 星期几的完整写法(Sunday)

%b 月名的缩写(Oct)

%B 月名的完整写法(October)

%c 本地日期和时间

%d 十进制日期

%D 日期08/20/99

%e 日期,如果只有一位会补上一个空格

%H 用十进制表示24小时格式的小时

%I 用十进制表示12小时格式的小时

%j 11日起一年中的第几天

%m 十进制表示的月份

%M 十进制表示的分钟

%p 12小时表示法(AM/PM)

%S 十进制表示的秒

%U 十进制表示的一年中的第几个星期(星期天作为一个星期的开始)

%w 十进制表示的星期几(星期天是0)

%W 十进制表示的一年中的第几个星期(星期一作为一个星期的开始)

%x 重新设置本地日期(08/20/99)

%X 重新设置本地时间(120000)

%y 两位数字表示的年(99)

%Y 当前月份

%Z 时区(PDT)

%% 百分号(%)

格式:strftime( [format specification][,timestamp] )

 

24.用户自定义函数

脚本中凡是可以出现模式操作规则的位置都可以放置用户自定义的函数。

格式:函数名(参数,参数,参数, ...){

语句

return表达式

(注:return语句和表达式都是可选项)

}

变量以参数值的方式传递,且仅在使用它的函数中局部有效。函数使用的只是变量的副本。数组则通过地址或引用被传 递,因此,可以在函数中直接修改数组的元素。函数中的变量只要不是从参数列表传来的,都视为全局变量。调用函数时,如果没有指定某个形参的值,该参数被初 始化为空。

23

long@long-Ubuntu:~$ cat grades

44 55 66 22 77 99

100 22 77 99 33 66

55 66 100 99 88 45

long@long-Ubuntu:~$ cat sorter.sc

#Scriptname: sorter

#It sorts numbers in ascending order

function sort(scores, num_elements, temp, i, j){

#temp,i,j will be local and private

#with an initial value of null

for(i=2; i<=num_elements; ++i){

for(j=i; scores[j-1]>scores[j]; --j){

temp = scores[j]

scores[j] = scores[j-1]

scores[j-1] = temp

}

}

}

{for (i=1; i<=NF; i++)

grades[i] = $i

 

sort(grades,NF)

for(j=1;j<NF;++j)

printf("%d ", grades[j])

printf("/n")

}

long@long-Ubuntu:~$ awk -f sorter.sc grades

22 44 55 66 77

22 33 66 77 99

45 55 66 88 99

 

25.杂项

固定字段

有些数据没有明显的字段分隔符,却有固定宽度的列。预处理这些数据时,substr很有用

空字段

用固定长度的字段来存储数据,就可能出现一些空字段,substr可以被用来保存字段,而不考虑它们是否包含数据

 

 

26.awk命令选项

-F fs or --field-separator fs

指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:

-v var=value or --asign var=value

赋值一个用户定义变量。

-f scripfile or --file scriptfile

从脚本文件中读取awk命令。

-mf nnn and -mr nnn

nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。

-W compact or --compat, -W traditional or --traditional

在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。

-W copyleft or --copyleft, -W copyright or --copyright

打印简短的版权信息。

-W help or --help, -W usage or --usage

打印全部awk选项和每个选项的简短说明。

-W lint or --lint

打印不能向传统unix平台移植的结构的警告。

-W lint-old or --lint-old

打印关于不能向传统unix平台移植的结构的警告。

-W posix

打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符****=不能代替^^=fflush无效。

-W re-interval or --re-inerval

允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]

-W source program-text or --source program-text

使用program-text作为源代码,可与-f命令混用。

-W version or --version

打印bug报告信息的版本。

 

http://blog.csdn.net/longwen7/article/details/6336757

分享到:
评论

相关推荐

    awk介绍

    awk介绍:This is a brief introduced awk document.

    awk 介绍,unix shell

    awk 介绍.awk unix shell

    shell编程指南,shell脚本,本书共分五部分全。grep家族,sed,AWK,正则表达式,tr用法

    第9章 AWK介绍 66 第10章 sed 用法介绍 89 第11章 合并与分割 104 第12章 tr用法 119 第三部分 登录环境 第13章 登录环境 125 第14章 环境和shell变量 132 第15章 引号 146 第四部分 基础shell编程 第16章 shell...

    Awk介绍及print语句

    NULL 博文链接:https://zhouzaibao.iteye.com/blog/664909

    awk 介绍。。。awk

    a w k是所有s h e l l过滤工具中最难掌握的,不知道为什么,也许是其复杂的语法 或含义不明确的错误提示信息。在学习a w k语言过程中,就会慢慢掌握诸如Bailing out 和 a w k : c m d . L i n e :等错误信息。...

    awk的详细介绍,awk的使用介绍

    awk的详细介绍,awk的使用介绍,awk的使用教程,awk的学习宝典

    学习和理解AWK的最佳书籍Effective AWK Programming

    这本书对awk的编程模型、基本语法有简单明了的介绍,在进行数据处理、文本处理、报表、试验算法方面的应用也有很多好的实例。  由于是88年的老书,其中对gawk最新版本对awk的扩展没有提及,但这并不妨碍其称为一本...

    AWK-4121介绍

    AWK-4121系列室外无线AP/网桥/客户端为工业应用提供了理想的 3合1无线解决方案,适用于不便接线、布线成本昂贵或使用移动 TCP/IP网络连接设备的场合

    shell中的精髓_sed_awk

    这个是关于shell中的sed和awk介绍的pdf文件,希望大家喜欢!!!

    Sed与awk 中文第二版

    第二版介绍了awk的posix标准,同时介绍了一些可免费使用的以及商业版的awk。 本书在一开始就给出了一个概述和指南,论述了从grep到sed再到awk不断改进的功能。sed和awk具有相同的命令行语法,以脚本的形式接收用户的...

    最牛逼的Linux awk命令详细介绍和实例快速学习

    最牛逼的Linux awk命令详细介绍和实例快速学习

    Awk学习笔记和指南

    awk 是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它...下面介绍的awk是以GUN的gawk为例的,在 linux系统中已把awk链接到gawk,所以下面全部以awk进行介绍。

    awesome-awk:精选的 AWK 框架、库、软件和资源列表

    完整的文档、指南和书籍快速指南 Unix/Linux 中的 AWK 命令以及 Anshika Goyal 和 Praveen Negi 的示例来自 GNU AWK 文档的一些简单示例Awk - 教程和介绍awk 示例第 1 部分,第 2部分,第 3 部分Frank Moraes 的 Awk...

    LINUX与UNIX_Shell编程指南

    第9章 AWK介绍 第10章 sed 用法介绍 第11章 合并与分割 第12章 tr用法 第三部分 登录环境 第13章 登录环境 第14章 环境和shell变量 第15章 引号 第四部分 基础shell编程 第16章 shell脚本介绍 第17章 条件测试 等等...

    awk_tawk:关于AWK多么令人敬畏的闪电演讲,特别是对AWK编程语言的回顾

    介绍AWK的出色表现,包括对AWK编程语言的回顾 还包括一个用AWK编写的演示工具。 吃自己的狗食或什么! SS=1 awk -f ./present.awk slides.txt ...其中SS可以选择提供起始幻灯片编号。 按下Enter键即可前进幻灯片...

    UNIX 快速查询手册

    UNIX 快速查询手册 1. 自举和关机 2 2. 用户权限与系统安全 2 3. 文件系统(包括UFS、NFS以及共享... awk介绍 21 14. sed介绍 25 15. tr介绍 27 16. Vi的三种工作状态 28 17. MAKE介绍 31 &lt;br&gt;

    sed ,awk用法

    sed,awk用法,sed,awk是linux开发必备知识,公司常用技术,很好很强大的sed和awk用法介绍,绝对值得您收藏学习。好资源大家一起分享!

    shell awk实用实例教程

    shell awk 实用程序 介绍awk的使用用例 对于处理文件内容比较方便 供学习参考使用

    Linux Shell编程教程

    第9章AWK 介绍 第10章sed 用法介绍 第11章合并与分割 第12章tr 用法 第13章登录环境 第14章环境和shell变量 第15章引号 第16章shell脚本介绍 第17章条件测试 第18章控制流结构 第19章shell 函数 第20章向脚本传递...

    Unix shell 基础知识普及

    9. AWK 介绍 10. sed 用法介绍 11. 合并与分割 12. tr 用法 13. 登录环境 14. 环境与 SHELL 变量 特定s h e l l变量 15. 引号 16. SHELL 脚本介绍 17. 条件测试 18. 控制流结构 19. SHELL 函数 20. 向脚本传递参数 ...

Global site tag (gtag.js) - Google Analytics