awk编程基础(1)

第一章 简介 awk是Unix操作系统提供的一个程序化语句,是为了使信息和文本的处理更易于表达和完成而设计的。它对于资料的处理具有很强的功能:对于文本文件里的内容做修改、对比、抽取等的处理,可以以很短的语句轻易完成。而象 C 或 Pascal 等高级语言要完成上述的动作,相对要麻烦得多。 awk 是在一组输入信息或文件上运行的,它浏览输入行,按照行次顺序,一次一行地进行处理。在一行中寻找程序中描述的模式,发现该模式,则进行相应的操作,处理完一行后,再进行下一行的处理,直到文件结束。 从awk在操作系统中所处的位置(/usr/bin/awk)来看,awk是Unix的一个命令;从它提供的内部语句来看,awk又象是一个程序语言。在以后的讨论中称它为语句或程序,但这都没什么区别。 awk 这个名字是由它的几个设计者姓氏的第一个字母而命名:Alfred V. Aho, Peter J. Weinberger, Brian W. Kernighan。awk最初在1977年完成,后来又经过多次修改,这里讨论的awk 实例都是在SCO UNIX 3.0 上通过的。 第二章 基础知识 2.1.基本程序结构 awk 程序是由若干个“模式”与“动作”所组成的,其执行方式是针对文件中的每一行(line)搜索指定的模式 (patterns),当一行中有符合指定的模式,awk 就会在此一行执行被指定的动作(actions)。 awk 依此方式处理输入文件的每一行直到输入文件结束。 “动作”一般写在大括号 “{ }” 里面,一个模式后面就跟着一个动作,一个动作可以是一条或多条语句。整个 awk 程式就象下面的形式: awk ‘ 模式 { 动作 } ................. 模式 { 动作 }’ filename 这种形式是从filename文件中读入数据 或者 `命令|awk ‘模式 { 动作 } .............. 模式 { 动作 }’` 是通过管道将命令的输出传递给awk语句。 例:awk ‘$1=”127.0.0.1” { print $2 }’ /etc/hosts #从/etc/hosts中读入数据 而:cat /etc/hosts| awk ‘$1=”127.0.0.1” { print $2 }’ #则是接收cat /etc/hosts的结果 两个例子都是将/etc/hosts文件中所有第一个字段为127.0.0.1的行的第二个字段打印出来。 其运行结果为:localhost 在 awk 中,“模式”或“动作”能够被省略,但通常是省略模式。模式被省略后,对于输入文件里面的每一行,动作都会被执行。而如果“动作”被省略,awk语句只会去寻找你所指定的模式,但即使找到了也不执行其它任何操作(因为没有指定动作),就象在Unix系统中你用find命令去寻找一个文件,但是没有用 –print 参数来说明要显示一样,find只是找到了这个文件,但并不显示出来。 如:awk ‘{ print $2 }’ /etc/hosts 的含义为:从/etc/hosts文件中读入数据,将每个记录(行)的第二个字段打印出来 结果为:localhost peixun1 而:awk ‘$1==”127.0.0.1”’ /etc/hosts 只是在/etc/hosts文件中寻找,看看哪一行的第一个字段为127.0.0.1,不管找到与否,一概不显示。 所以结果是:什么都没有 2.2.如何执行awk语句 基本上,有三种方法可以执行awk语句。 1) 如果 awk 程序很短,则 awk 可以直接写在命令行上(command line),如下 所示: #awk 'program' input-file1 input-file2 ... 其中 program 包括一些模式和动作,就象前面的例子一样。input-file1 input-file2 ...为数据文件名,程序将从中读取数据。文件名可以多于一个,当同时存在多个文件名时,程序将顺序处理这些文件。 2) 如果 awk 语句较长,较为方便也是通常的做法是将整个 awk语句存放在一个文本文件中,通过文件名来执行这段程序。 如一个awk命令的所有语句都放在了一个叫mypro的文件中,那么可以通过下面的方式来执行:#sh mypro 3)也可以只将 'program' 部分即“模式与动作”部分写在文件中,通过以下的方式执行: #awk -f program-file1 -f program-file2 ...input-file1 input-file2 ... 其中,program-file1 ,program-file2是存放“模式与动作”的文件名称,他通过 -f 参数被调用,命令文件的个数也可以有多个,在使用时,每个文件名前面都必须要有-f 参数。 如:文件file1的内容为:‘{ print $1,$2,$3 }’ file2为:‘{ print $2,$3,$4 }’ file3为: I am a student file4为: You are a teacher 则:执行 awk -f ./file1 -f ./file2 ./file3 ./file4 的结果为:I am a am a student You are a are a student 我们建议使用第二种方法,简单而又方便。 2.3 变量 awk中的变量和Shell中的变量相似,都不用事先定义,也没有类型的区别(都是字符串型),在使用时可随时进行定义。awk中的变量分以下几种: 1)字段变量 awk处理数据时是逐行进行处理的,字段变量就是在处理过程中表示当前记录各字段的变量,其形式和含义如下: $0: $0就是所处理的当前行(字符串) $1: 当前行(记录)的第一个字段 $2: 当前行(记录)的第二个字段 $3: 当前行(记录)的第三个字段 ……… 如: awk ‘{ print $1,”|”,$2 }’ /tmp/test 该语句将/tmp目录下的test文件的第一和第二个字段打印出来,字段间的分隔符为”|”. 3) 内部变量 awk的每次执行,都建立了一些缺省的变量,也叫做内部变量,这些变量有固定的名字和固定的含义,它们在程序运行期间可以随时被引用。其具体定义如下: FS: 输入记录字段间的分隔符 RS: 输入记录的分隔符 OFS: 输出记录字段间的分隔符 ORS: 输出记录的分隔符 NR: 当前行数 NF: 当前记录字段数 ARGC: 命令行变元数 前四个内部变量在使用时一般用于设定你所需要的分隔副符,具体的使用方法如下例所示: awk ‘BEGIN { FS=”|” ;OFS=”|” } #指明输入输出时都以“|”为字段间的分隔符 { print $1,$2,…… }’ 文件名 后面三个内部变量用于模式部分较多,在动作部分也有使用。 awk ‘ NR=10 { print $1,$2,…… }’ 文件名 #用于限定只对第十行进行处理。 awk ‘ BEGIN { SUM=0 } #对SUM变量赋初值 { SUM=SUM+NF } #利用NF变量获得每行字段数的总和 END { print “本文总共” SUM “个字段” }’ 文件名 关于BEGIN和END的用法将在第三章介绍。 3)自定义变量 在awk语言的任意动作区间,即在{}之内,均可随时定义变量,无须事先说明。但一般情况下是在BEGIN中定义变量并赋以初值,在动作区域内使用。 如:awk ‘BEGIN { sum=“0” } #定义变量sum,其初值为0 { sum=sum+1 } #对于每一条记录变量sum加1 END { print sum }’ file0 整条语句将计算出文件总的字段数。 第三章 模式(pattern) 在一条“模式-动作”语句中,模式是一个表达式,用来确定执行相关操作的那些记录(行)。也就是在awk处理数据时,只有数据行与模式(pattern)相匹配,程序中相对应的动作(action)才会被执行。 3.1 BEGIN和END BEGIN和END是两个特殊的模式。 BEGIN的作用是在处理第一条记录之前将BEGIN后面大括号之内的动作运行且只运行一次,也就是BEGIN匹配第一个输入记录之前。 END的作用是在处理完最后一条记录之后将END后面大括号之内的动作运行且只运行一次,也就是说,END匹配最后一个输入记录之后。 如:awk ‘BEGIN { print “my program begin !”;i=0 } { i=i+$1 print $1 } END { print “total :”,i }’ file0 如文件file0的内容为: 3 4 2 8 则运行结果为: my program begin !#在处理文件file0第一条之前,由BEGIN的print动作显示 3 # 2 #这两行是print $1语句的结果,直接将第一个字段打印出来。 total :5 #在处理完文件file0最后一条记录之后,由END的print动作显示 3.2 用表达式(Expression)作为模式 一个awk模式可以是一个表达式,用这个表达式来测试两个数字或字串的诸如大于、等于、小于等关系。awk有六个关系操作符和两个匹配符: x y 如果 x 大于 y,则结果为真。 x>=y 如果 x 大于、等于 y,则结果为真。 x==y 如果 x 等于 y,则结果为真。 x!=y 如果 x 不等于 y,则结果为真。 x~y 如果 x 符合 regular expression y,则结果为真。 x!~y 如果 x 不符合 regular expression y,则结果为真。 上面所提到的 x 与 y,如果二者皆是数字则视为数字之间的比较,否则它们会被转换成字符串且以字符串的形式做比较。两个字符串的比较,会先比较第一个字符,然后比较第二个字符,依此类推,直到有不同的地方出现为止。如果两个字符串在较短的一个结束之前是相等,则视为 长的字符串比短的字符串大。例如 "10" 比 "9" 小,"abc" 比 "abcd" 小。 例:awk ‘$1>5{ print $0 }’ file0 其结果是把文件file0中第一个字段大于5的所有行打印出来。 3.3 用正则表达式(Regular Expressions)作为模式 awk还提供了比前面介绍的功能更强的字符串查找模式。这些模式称做正则表达式,最简单的正则表达式是以斜杠“/”括起来字符串,例如:/Asia/ 一个regular expression (正则表达式)可简写为 regexp,当输入记录含有 regexp 时就视为符合。如上例中的/Asia/,对于任何输入记录,若含有'Asia'则视为符合。 例如:awk '/Asia/ { print $2 }' earth 结果将把文件earth中所有含'Asia'的行的第二个字段打印出来,而不论'Asia'这个字符串在一行中的那一部分。 通常,为了将一个匹配限制在一个特定的域上,可以使用匹配操作符~(匹配)和!~(不匹配)。 如:awk '$2 ~ /Asia/ { print $0 }' file0 将把文件file0中第二个字段是字符串Asia的行全部打印出来。 而:awk '$2 !~ /Asia/ { print $0 }' file0 将把文件file0中第二个字段不是字符串Asia的行全部打印出来。 在正则表达式中,符号 / ^ $ . [ ] * ? ( ) 是元字符,这些元字符象UNIX Shell中的元字符一样有特殊的含义。例如,元字符“^”和“$”分别匹配字符串的开始和结束,而元字符“.”匹配任意单个字符。如 /^.$/ 将匹配所有只包含一个字符的输入行。 由括号括起来的一组字符,表示匹配其中的任何一个字符。如/{ABC}/与那些无论在什么地方包含A,B,C中任一字符的记录相匹配。 多个字符或数字可以在括号内采用缩写形式:/[a-z]/,它与所有纯小写字母字符串相匹配。 /^[0-9]+$/匹配所有以数字开头的字符串。 在元字符的前面加上一个“/”,就可以关闭元字符的特殊含义。这样,/b/$/匹配所有包含b$这两个字符的行。 3.4 模式组合 一个组合的模式是由较简单的模式加上圆括号和逻辑操作符&&"与",||"或",!"非"来构成。 例如: awk '$1==”Asia” && $3>500 { print $0 }’earth 将文件earth中所有第一个字段为Asia,且第三个字段大于500的行打印出来。 awk '$1==”Asia”||$1==”Africa” { print $0 }’earth awk '$1~/^(Asia|Africa)$/ { print $0 }’earth 以上两句都是将文件earth中所有第一个字段为Asia或者为Africa的行打印出来。 awk '$1!=”Asia” && $1~/^[As]/ { print $0 }’earth 将文件earth中所有第一个字段包含As但不为Asia的行打印出来。 非操作符!的优先级最高,其次是&&,最后是||。操作符&&和||从左到右判断它们的操作数,当得到真或假值时,这种判断即停止。 第四章 动 作 4.1.1 输入 awk所处理的数据可以从指定的文件中读取或者接收某些命令的执行结果,再或者可以直接从标准输入设备上输入。 1)从文件中输入 格式为: awk ’{ action }’ filename1 filename2 ... 执行时,awk将依次从filename1 filename2 ...文件中读取数据并执行action操作. 如: awk ’{ print $1 }’ file1 从文件file1中读取数据,并将打印每行的第一个字段 2)从其它命令输入 格式为: Unix命令| awk ’{ action }’ 执行时,awk将接收Unix命令的输出,并对输出执行action操作. 如: who| awk ’{ print $2 }’ 如果who命令结果为: root ttyp0 Jul 6 14:19 则上面awk语句的执行结果为:ttyp0 3) 从标准输入设备上输入 在命令行上输入awk ’{ action }’ 并回车后 awk语句便处于等待状态,此时可以输入一条记录,当打回车确认后,awk语句将对这一行进行处理。如果符合处理的条件,awk就会将处理结果显示到屏幕上。接着,再次进入等待输入的状态。如此循环下去,一直到打Ctrl-d退出或被del键中断。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值