awk编程

来源:互联网 发布:2016淘宝视频开店教程 编辑:程序博客网 时间:2024/05/22 15:44
一、awk编程模型
  awk程序由一个主输入循环维持,按行输入,反复执行,知道终止条件被触发。
   awk定义了两个特殊字段:BEGIN 和END,BEGIN用于在主输入循环(读输入文件)之前执行,END用于在主输入之后执行。

二、awk几种简单的用法
注:input是一个ASCII文件,其中包含三个空行
   (1)~~~>awk'/^$/{print "there is a 空行."} input
     ~~~>there is a 空行.
     ~~~>there is a 空行.
     ~~~>there is a 空行.
   (2)通过脚本(编写awk命令)
     创建comman.awk脚本文件,内容为:
/^$/{print "there is a 空行."}
     然后运行命令
     ~~~>awk -f comman.awk input
     ~~~>there is a 空行.
     ~~~>there is a 空行.
     ~~~>there is a 空行.
   (3)通过纯脚本
     创建src.awk脚本文件,内容为:
#!/bin/awk -f
/^$/{print "there is a 空行."}
     然后直接执行脚本文件,输出结果同上

三、记录和域
   记录:awk输入文件行
  域:记录中的每个字符串(域之间用空格、Tab键或其他符号进行分隔)(分隔符)
     ~~~>awk '{print $1,$2,$3}' input
     ~~~>awk -F"," '{print $1,$2,$3} input
     ~~~>awk -F"\t" '{print $1,$2,$3} input
     ~~~>awk 'BEGIN {FS=","} $1~/root/' /etc/passwd
     ~~~>awk 'BEGIN {FS="\t+"} {print $1,$2,$3}'input
   注:$0 表示所有域,$n表示第n个域

四、awk环境变量及其意义
   变量名 意义
   $n当前记录的第n个域,域间由FS分割
   $0 记录的所有域
   ARGC 命令行参数的数量
   ARGIND命令行中当前文件的位置(以0开始标号)
   ARGV 命令行参数的数组
   CONVFMT 数字转换格式
   ENVIRON 环境变量关联数组
   ERRNO 最后一个系统错误的描述
   FILEDWIDTHS字段宽度列表,以空格键分隔
   FILENAME 当前文件名
   FNR 浏览文件的记录数
   FS 字段分隔符,默认是空格键
   IGNORECASE布尔变量,如果为真则进行忽略大小写的匹配
   NF 当前记录中的域数量
   NR 当前记录数
   OFMT 数字的输出格式
   OFS 输出域分隔符,默认是空格符
   ORS 输出记录分隔符,默认是换行符
   RLENGTH由match函数所匹配的字符串长度
   RS 记录分隔符,默认是空格键
   RSTART由match函数所匹配的字符串的第1个位置
   SUBSEP数组下标分隔符,默认值是\034

五、格式化输出
   printf(格式控制符,参数)
   printf修饰符:
printf("%-15s",$1) 输出字符串,左对齐,长度为15
printf(".3f",2009.1012) 浮点数长度控制在10位、小数点后保留3位
printf("%.3f",2009.1012)

   printf格式符及其意义:
%c ASCII字符
%d 整型数
%e 浮点数,科学计数法
%f 浮点数
%o 八进制数
%s 字符串
%x 十六进制数

六、内置字符串函数及其意义
函数名 意义
gsub(r,s) 在输入文件中用s替换r
gsub(r,s,t) 在t中用s替换r
index(s,t) 返回s中字符串第一个t的位置
length(s) 返回s的长度
match(s,t) 测试s是否包含匹配t的字符串
split(r,s,t) 在t上将r分成序列s
sub(r,s,t) 将t中第1次出现的r替换为s
substr(r,s) 返回字符串r中从s开始的后缀部分
substr(r,s,t) 返回字符串r中从s开始长度为t的后缀部分

例:
~~~>awk 'BEGIN {FS=":";OFS=":"}gsub(/root/,"Teisei",$1) {print $0}' /etc/passwd
~~~>awk 'BEGIN {FS=":";OFS=":"}gsub(/root/,"Teisei") {print $0}' /etc/passwd
~~~>awk 'BEGIN {printindex("gridsphere","ph")}'
~~~>awk 'BEGIN {printlength("gridsphere")}'
~~~>awk 'BEGIN {printmatch("gridsphere",/D/)}'
~~~>awk 'BEGIN {IGNRECASE=1;printmatch("gridsphere",/D/)}'
~~~>awk 'BEGIN {str="multiprocessorprogramming";sub(/pro/,"PRO",str);printf("%s\n",str)}'
~~~>awk 'BEGIN {FS=","} {$1~Lisub(/10/,"99",$0);print $0}' input
~~~>awk 'BEGIN {str="multiprocessorprogramming";print substr(str,6)}'
~~~>awk 'BEGIN {str="multiprocessorprogramming";print substr(str,6,9)}'
注:split在后面结合数组进行介绍

七、向awk脚本传递参数
awk 脚本 parameter=value 输入文件(等号两端不能有空格)
awk 'BEGIN {FS=","} {print NR,$0}' OFS="." input
注意:awk命令行参数不能被BEGIN字段语句访问,换句话说直到输入文件的第1行被读取时,命令行参数方才生效

八、条件语句和循环语句
(语法和C语言完全一样)
(1)if(条件表达式)
动作1
  [else
动作2]
(2)if(x~/[Hh]el?o/) print x
(3)while(条件表达式)
动作
(4)do
动作
  while(条件表达式)
(5)for(设计计数器初值;测试计数器;计数器变化)
动作

九、数组
基本格式:array[index]=value
1.关联数组:
关联数组的值无需以连续的地址进行存储,awk自动维护了一对值:索引和数组元素值。awk的所有数组都是关联数组。
~~~>awk'BEGIN{data[10.15]="1200";CONVFMT="%d";printf("<%s>\n",data[10.15])}'
(CONVFMT=“%d”字符转换格式为整型,10.15-->10,data[10]不存在,data[10.15]存在)
基于上述关联数组的含义,awk特别定义了一种for循环用来访问关联数组:
for(variable in array)
do something with array[variable]
关键字in也可以用在条件表达式中判断元素是否存在数组中,条件表达式格式为:
index in array
如果array[index]存在,则返回1,否则返回0。
~~~>awk '
~~~>BEGIN {data[10.15]="1200";
~~~>if("10.15" in data)
~~~>print "Found element!"}'
~~~Found element!

2.split函数
split(r,s,t)函数将字符串以t为分割符,将r字符串拆分为字符串数组,并存放在t中。返回值是数组的大小。
~~~>awk 'BEGIN {printsplit("abc/def/xyz",str,"/")}'
~~~3
~~~>awk 'BEGIN {FS=","} {print split($1,name,"")}' input
~~~2
~~~2
~~~2
下面看看split函数所生成的数组内容,新建名为array.awk的脚本文件,内容如下:
#!/bin/awk -f
BEGIN {FS=","}
{split($1,name," ");
for(i in name)   print name[i]}
执行脚本
~~~>chmod 744 array.awk
~~~>./array.awk input
在split函数分割第1号域之后,利用for循环将name数组的内容打印出来。

3.数组形式的系统变量
awk系统变量中有两个变量是以数组形式提供的:ARGV和ENVIRON。ARGC是ARGV数组中元素的个数,与C语言一样,从ARGV[0]开始到ARGV[ARGC-1]结束。
(1)ARGV
例1:新建脚本文件argv.awk内容如下:
#argv演示ARGV中存储了哪些命令行参数
BEGIN { for(x=0;x<ARGC;x++)
print ARGV[x]
print ARGC
}
执行:
~~~>awk -f argv.awk xyz n=99 "HelloWorld"
例2:对input文件中的电话号码进行检索,即输入姓名,系统响应输出其电话号码。新建名为findphone的脚本:
#例2
#!/bin/awk -f
BEGIN { FS=",";
#判断是否已经输入姓名
if(ARGC>2) {
   name=ARGV[1];
   delete ARGV[1] }
else {
#若没有输入姓名,提示输入姓名
while(!name){  print "Pls. Enter aname";
getline name< "-"}
}
}
$1~name  { print $1,$3}
(2)ENVIRON变量存储了Linux操作系统的环境变量
例:打印出当前系统所有的环境变量,其结果类似Linux的set命令
~~~>awk '
~~~>BEGIN { for(i in ENVIRON)
~~~>print i "=" ENVIRON[i]}'
ENVIRON的索引是环境变量名,因此可以通过环境变量名来直接得到其值:
ENVIRON["USER"]
ENVIRON["AWKPATH"]
当然也可以修改环境变量值
ENVIRON["GRIDSIM"]=/bin.gawk
注意:环境变量名需要用双引号引起
0 0
原创粉丝点击