分类: LINUX
2009-10-04 01:38:20
awk程序调用,以参数的形式包含在awk命令后,然后再跟上输入文件的名称。
例如:$awk '/widgt/{print $1}' phones
目标:用//括起来
操作:包含在{}中。
单引号'':为了防止shell将其内容解释为分开的两个参数,或shell的另一部分指令。
awk调用的三种方式:
第一种:命令行方式:
awk [-F fild-separator] 'commands' input-file(s)
-F:是指定域分隔符,默认为空格。
例如: awk -F: 'commands' input-file(s)
第二种:将所有awk命令插入一个文件,并使awk程序可执行,然后用awk命令解释器作为脚本的首行,以便通过输入脚本名称来调用它。
第三种:将所有的awk命令插入到一个单独文件,然后调用
例如:
awk -f awk-script-file input-file(s)
-f选项指明在文件awk_script_file中的awk脚本,input_file(s)是使用awk进行浏览的文件名。
1、一个awk程序是包含一个个模式和操作的集合。
$ awk '{print $1}' phones
打印出文件phones中每行的第一个字段的内容。
awk程序可以自动的将每行分成相应的字段:$0表示整个行或者记录,$1表示每行的第一个字段,$2表示第二个,$3。。。
字段的分隔是依靠字符的分隔符实现的。默认的字段分隔符是空区,包括任意数目的空格(space)或者跳格键(tab)。
用户可以使用-F的选项来在awk命令行下定义自己的字段分隔符。
2、模式
1)字符串模式
查找某行中某一特定的字或字符串,只需将其放在斜线之中
如:/Russule/
将匹配出任意含有字Russule的所有行
[1]一般表达式: 一个由字母、数字、特殊运算符集组成的字符串序列。
\t 跳格键扩展字符
\x:扩展字符
如:\n 换行符
^^:行开始部分
如:^my my在一行的开头
$:行结尾部分
如:word$ word在一行的结尾
[xyz] :字符集
如:[ab12] a,b,12种的任一个
x|y :x或y
如:RLF|RAF RLF或RAF
x* :0或者多个x
如:item_{a-z}* item_后面跟一个或多个小写字母
x+ :1或者多个x
如:^[a-z]+$ 只包含小写字母
x? :0或者1个x
如:^it?$"I"或"It"
[2]比较字符串
~:是否两个字符串匹配
例如:$2~/^15/,将检查字段2是否以15为开始
$2~/^15$/,检查第二字段是否刚好只含有字符串15而没有其他内容
!~:不含有匹配字符串的方式,!~第一个字符串中不含有第二个字符串。
==:检查两个字符串是否相同,而不是相互包含。
!=:检查两表达式的值是否不相等。
[3]、比较两个字符串的字母顺序
<、>、<=、>=字符串之间是一个字符一个字符来比较的。
2)复合模式
是把多个模式用逻辑运算符&&、||、!结合起来而组成的模式。
3)范围模式
范围模式的句法为:
pattern1,pattern2
4)数值模式
上面涉及大部分字符串模式同样适用于数值模式,除了一般表达式及字符串匹配波浪运算符,用户不必一定确定是字符串还是数值模式,awk用上下文来字段判断哪一个合适。
5)开始与结束模式
开始(BEGIN)与结束(END)模式是为了将用户的awk程序中的一部分与检查每行输入的awk循环分开而产生的。开始模式在任意一行被读取之前应用,而结束模式在最后一行被读取之后被应用。
用户经常需要在awk程序主循环前设置一个变量或打印一个标题。
开始模式的另一个用途是在模式匹配循环之前定义变量。
结束模式与开始模式相似,但是它是在所有输入都完成之后才进行其相应的操作。
例如
BEGIN{FS=",";print "Name On hand Cost Price"}
$awk 'END {print NR}' inventory,这里从inventory文件中读取所有行,然后打印记录的数目。这里使用了awk的内置变量NR。
3、动作
1)变量
awk程序运行用户自己设置变量,或给它们赋值,以及对它们进行操作。变量可以包括字符串与数值。
一个变量名可以由字母与数字序列组成,且必须以字母开头,下划线也可以作为变量的一部分。
awk不需要被指名为字符或者数字类型,它们自动被赋予其正确使用的类型,所以的变量开始时都自动被置为NULL或者0。
变量除了用户自定义的之外都是全局变量,即在整个awk程序中都有效。
2)内建变量
FS:输入分隔符
OFS:输出分隔符
NF:当前记录的字段数
NR:当前为止的字段数
FILENAME:输入的文件名
FNR:当前文件的记录数
RS:输入记录的分隔符
ORS:输出记录的分隔符
OFMT:输出数据格式
RLENGTH:匹配功能设置的匹配长度
RSTART:匹配功能设置的匹配起始位置
SUBSEP:下届分隔符,用于数组
ARGC:命令行参数
ARGC:命令行参数数组
[1]、与字段及字段数目有关的操作
NF变量最方便的用法,就是在一个字段数不固定的当前记录中找到其最后一个字段。$NF,这个就是每个记录中最后一个字段的内容。
[2]、字符串函数及其操作
给变量赋值;例如:label = "inventory"
将两个字符串相连;
这个操作没有一个专用的运算符,为了连接两个字符串,用户可以紧跟第一个字符串后面写下第二个字符串。
例如:code=$6"001"
字符串函数;
length:返回字符串长度
match:在字符串中查找一个一般表达式
sub:用一个确定的表达式代替一个字符串
gsub:在所有匹配成功的地方替换某一字符串
gawk还提供了一些函数(如toupper和tolower)来改变字符串的大小写。
使用逻辑运算符建立复合模式;
两个字符串变量或字符串表达式可以使用||、&&、!来连接起来。
例如:$1=="Yankees"||$4=="Knicks",匹配所有第一个字段Yankees或第四字段为Knicks的记录
3)数值运算符及其操作
awk程序提供了大量的函数及运算符来处理数值及数值变量。
算术运算符包括+、-、*、/、%和^。%,取余,^表示指数运算。
cos、atan2三角函数;
log、exp指数、对数函数;
int将一数值转变为整数;
rand产生一个0到1之间的随机数。
4)、数组
确定数组:
用户在给数组元素赋值之前不必声明或定义数组,通过给一元素赋值来定义一个数组,例如:stock[1]=$2;
可使用一字符串作为数组元素的标识符。
number[$1]=$2
使用数组:
使用for-in语句来依次遍历所有的下标。
例如:
^.DS/{count["display"]++}
^.BL/{count["bullet"]++}
^.TS/{count["table"]++}
END {for (s in count) print s, count[s]}
用delete删除一个数组元素
delete array[subscript]
使用subscript检查数组中是否有元素的下标与指定的相同
subscipt in array
如果存在array[subscript],即指定数组有特定下标标出的元素,则此表达式返回1,否则返回0。
5)、用户定义函数
定义函数:
确定名称,需要的参数,所做的工作是什么;样式如下:
function function_name(list of parameter)
{
action_list
}
注意:函数名与括号之间一定不能有空格,括号内是此函数的参数表。函数返回的部分是可有可无的,但如果不写,函数是不会返回值的。
调用函数:一旦定义了一个函数,就可以像内建函数一样使用它。
6)、控制语句
[1] if语句
if(condition)action
expression1?expression2:expression3
[2]while语句
while(condition)
{
action
}
do action while(condition)
[3]for语句
for(initial statement; test; increment) statement
[4]break和exit语句
4、输入
1)从文件中读取输入
一般情况下,awk程序操作用户输入命令所指定文件中的信息。它从输入文件中一次读取一行,并在程序中应用模式/操作对。
使用getline函数从键盘或其他文件读取一行输入。
使用getline读取一行,然后在getline函数后放上一个变量名,可以将一行的内容赋给此变量
如:getline X
如果要从其他文件中读取输入,则可以为getline重定向输入文件。
例如:getline<"my_file",从文件my_file中读取my_file的内容。
getline var <"my_life",从my_file文件中读取一行并将其赋值给变量var。
注意:当给getline函数一个输入文件名时,必须将其置于引号之中。否则,它将被解释为一个存放文件名的变量名,该变量与文件名字相同。
2)从键盘读取输入
unix系统将键盘标识为/dev/tty文件,如果想从键盘读取输入,则应该使用/dev/tty作为getline函数后的文件名。
例如:
{print $1, "old price:",$4
getline new<"/dev/tty"
$4=new
print "New price:",$0>"outputfile"}
注意:因为/dev/tty是一个文件名,因此它也必须用引号括起来。这与一般文件相同。
3)、从管道中读取输入
使用管道可以将其他unix系统命令的输出作为awk输入。
例如;
sort input_life | awk 'program'
4)、在命令行上将参变量传递给程序
格式有2种:
直接输入程序名:
$awk 'program' v1 v2...
用一个保存过的程序文件
$awk -f program_file v1 v2...
命令行中的参数个数被存储在内建变量(ARGC)中。
这个数组名叫ARGV。awk命令自身被视为第一个参数,即ARGV[0]是awk,ARGV[1]是下一个命令行参数,依此类推。
在缺省状态下,awk将命令行上的名字视为输入文件。如果将它作为一个参变量,应当在开始语句BEGIN中读取其值,并将其设置为NULL,这样awk才不会将其视为输入文件名。
命令:
BEGIN {temp=ARGV[1];ATGV[1]=""}
5)、多行文件和记录分隔符
awk默认的记录分隔符为换行符。使用awk的内置变量RS与ORS,可以选择任意字符作为记录分隔符。
最简单的多行文件使用一空行分隔记录。要想awk使用一空行当作当前程序的记录分隔符,先用开始语句BEGIN在程序的开始部分将字段分隔符置为空NULL。
例如:BEGIN(RS=" ")之后,就可以像读其他记录一样读取多行记录了。
若改变以空格位默认值的字段分隔符,如改成一个换行符,可以用以下语句:
BEGIN{RS=" ";FS="\n"}
5、输出
1)、print
格式为:
print expr1, expr2...
若想使输出的字段被分隔符所分隔,那么其中的逗号是必不可少的。如果缺了逗号,打印出来的结果将是无分隔符分隔的。切记,如果想打印一个字符串,一定要用引号把它括起来,要不会视为一个变量而不是字符串。
可以通过设置输出字段分隔符(OFS)这个内建的变量来控制字段分隔符。
2)、printf
格式化输出
3)、传递输出到多个文件中
使用重定向
$awk '{print $1,$2,$4}' inventory>invent.new,将文件inventory中的第三个字段丢下,其余部分用来新建一个文件invent.new
同样可以在一个程序内部使用文件重定向来发送一部分输出到一个文件,而另一个部分发送到另一个文件。这样可以将一个文件分为两个部分。
例如:
{if($6~"toy") print $0>>"toy_file"
else print $0>>"stat_file"}
6、用Shell来运行awk
例如:
计算单列数值的平均值:
#average:use awk to add colum of numbers
#usage:specify filename as argument
awk '{total+=$1}
END {print total/NR}' $*
这是一个调用了awk的shell脚本程序。$*是一个shell变量,就像$1是一个awk变量一样。多了一个附加的$*参数,它表示shell中放置命令行参数的方式。被shell($*)处理的命令的那部分要用引号括起来。在大括号中的$1参数在shell处理时被引号保护起来了。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/russule/archive/2009/02/13/3888239.aspx