AWK经典实例讲解二

合集下载

awk正则表达式和内置函数的使用方法实例详解

awk正则表达式和内置函数的使用方法实例详解

awk正则表达式和内置函数的使⽤⽅法实例详解awk正则表达式及内置函数实例详解:1、模糊匹配:复制代码代码如下:awk ‘{if($3~/97/) print $0}' data.f:如果第三项中含有”97”则打印该⾏awk ‘{if($4!~/ufcx/) print $0}' data.f:如果第三项中不含ufcx有则打印2、精确匹配:复制代码代码如下:awk ‘{if($5==66) print $0}' data.f:如果第五项是66则打印awk ‘{if($5!=66)print $0}' data.f : 如果第五项不是66则打印awk ‘{if($1>$5) print $0}' data.f:如果第⼀项⼤于第五项则打印3、⼤⼩写匹配:复制代码代码如下:awk ‘{if(/[Ss]ept/) print $0}' data.f:符合,则打印⼀⾏。

awk ‘/[Ss]ept/ {print $2}' data.f:符合,则打印第⼆字段4、任意匹配:复制代码代码如下:awk ‘{if($2 ~/^.e/) print $0}' data.f:第⼆字段中,第⼆个字符为e,输出awk ‘{if($4 ~/(lps|fcx)/) print $0}' data.f:第四个字段含有lps或fcx则输出5、&&,||:复制代码代码如下:awk ‘{if($3 ~/1993/ && $2==”sept”) print $0}' data.f:两边都真则输出awk ‘{if($3 ~/a9/ || $2==”sept”) print $0}' data.f:⼀边为真则输出6、变量定义:awk ‘{date=$2;price=$5; if(date ~/[Ss]ept/) print “price is ” price}' data.f:变量定义,满⾜date是sept或者Sept的将price输出。

awk用法精析

awk用法精析

AWK 用法简介概要AWK是Unix平台上一种可以对文本进行逐行处理的编程语言,它来源于3个创作者的名字:Aho、(Pet er)Weinberg和(Brain)Kernighan.与sed和grep很相似,awk是一种样式扫描与处理工具,但其功能却大大强于sed和grep。

awk提供了极其强大的功能:它几乎可以完成grep和sed所能完成的全部工作,同时,它还可以可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。

awk的三位创建者已将它正式定义为:样式扫描和处理语言。

AWK的调用方式1). 程序体直接写到AWK命令行中,适用较简单的情况awk 'program' input-file1 input-file2 ...2). 程序体写入文件中,用AWK命令调用该文件awk -f program-file input-file1input-file2 ...3). C shell作为命令解释程序,调用AWK来执行AWK程序,写成的脚本#!/bin/csh -fawk '{ print $8, "\t", $3} \'4). AWK作为命令解释程序,写成的脚本#!/bin/awk -f{ print $8, "\t", $3}AWK的参数说明awk [ -F re] [parameter...] ['prog'] [-f progfile][in_file...]awk –F"," '{}'参数说明:-F re: 允许awk更改其字段分隔符。

parameter: 该参数帮助为不同的变量赋值。

'prog': awk的程序语句段。

必须用单引号:'和'括起,以防被shell解释。

这个程序语句段的标准形式为: 'pattern {action}'(1) pattern参数是匹配模式,跟Sed命令类似。

awk用法总结(待续)

awk用法总结(待续)

awk用法总结(待续)使用awk脚本文件,需要注意以下情况:AWK脚本文件开头需要注明调用方式,典型写法为:#!/bin/awk -f注意-f后面有空格。

脚本文件需要有执行权限,如果没有需要赋予可执行权限脚本文件具体,打印话单第一个字段入234.txt,同时在屏幕上显示Hello World!tt.awk#!/bin/awk -fBEGIN{FS="|"}{print $1 >> "234.txt";}END{print ("Hello World!");}转载一份awk培训文档,转载来源:一、AWK简介AWK名字来源于三位创造者Aho、Weinberger和Kernighan统称。

AWK擅长处理文本数据。

二、AWK的调用方式awk [-Ffs] [-v var=value] [program | -f progfile ...] [file ...]1、命令行方式例如:2、文件方式例如:3、文件解释器方式AWK脚本文件开头需要注明调用方式,典型写法为:#!/bin/awk -f注意-f后面有空格。

脚本文件需要有执行权限,如果没有需要使用chmod +x progfile赋权。

例如:三、AWK参数-F 指定域分隔符,例如:-F "|",即以|作为域分隔符,默认分隔符为一个或多个空格或TAB,即"[[:space:]][[:space:]]*"。

-v 定义变量,从shell给awk传递变量,如-vDATE=$DATE,即将shell中$DATE变量值传递给awk变量DATE。

-f 指定脚本文件,例如-f progfile。

四、AWK内置变量FS 域分隔符NF 域个数NR 行数FNR 同上FILENAME处理的文件名,当输入为管道时,FILENAME为空。

RS 行分隔符OFS 输出域分隔符ORS 输出行分隔符OFMT 数字输出格式CONVFMT 数字内部转换格式SUBSEP 多维数组索引分隔符ARGC 输入参数个数ARGV 输入参数数组ENVIRON 环境变量数组RSTART match()函数正则匹配到字符串开始位置RLENGTH match()函数正则匹配到字符串的长度五、AWK内置函数blength[([s])] 计算字符串长度(byte为单位)length[([s])] 计算字符串长度(character为单位)rand() 生成随机数srand([expr]) 设置rand() seedint(x) 字符串转换为整型substr(s, m [, n]) 取子字符串index(s, t) 在字符串s中定位t字符串首次出现的位置match(s, ere) 在字符串s中匹配正则ere,match修改RSTART、RLENGTH变量。

awk基本命令小例子

awk基本命令小例子

=====================AWK如何选择正确行===============================awk如何工作:为方便解释awk程序的框架结构和有关术语(terminology),先以一个员工薪工资档案(emp.dat ),进行介绍,文件内容如下:A101 chenying 100 210A304 linxiyu 110 215S283 degnming 130 209S267 liuchao 125 220B108 hejing 95 210文件中各字段依次为:员工ID,姓名,薪资率,及实际工时。

ID中的第一码为部门名称代码,。

“A”,”B”,“S”分别表示”“accp部门”,“benet部门”,“市场部”。

[root@test740_9 jiaxin]# cat emp.datA101 chenying 100 210A304 linxiyu 110 215S283 degnming 130 209S267 liuchao 125 220B108 hejing 95 210其中A开头的表示accp部门工作人员,工资加薪5%,加薪后员工薪资仍低于110的,以110计。

编写awk程序打印新的员工薪资率报表。

[root@test740_9 jiaxin]# cat adjust1.awk#!/bin/awk -f{if($0~/A/){$3*=1.05}if($3<110){$3=110}printf("%s %-8s %d\n",$1,$2,$3)}[root@test740_9 jiaxin]# cat adjust2.awk#!/bin/awk -f{if($0~/A/){$3*=1.05;if($3<110){$3=110}}printf("%s %-8s %d\n",$1,$2,$3)}====================我是数组分隔符=======================建立一个kecheng.dat文件,内容学生选课内容,第一栏是学生姓名,其后是所学课程[root@test740_9 shuzu]# cat kecheng.datzhangsan math english chineselisi computer chinese englishwangwu dianzi chinese mathzhaoliu huanjing english chinese以文件kecheng.dat来统计学习各门课程的人数.需要存储两项信息: a) 课程名称,一共有哪些课程不确定b)各门课程的选修人数[root@test740_9 shuzu]# cat course.awk#!/bin/awk -fBEGIN{FS=" "{for(i=2;i<=NF;i++){number[$i]++;} #NF内置变量,当前行的字段数;数组number[]不用事先声明}END{for(course in number) printf("%10s %d\n",course,number[course]);}[root@test740_9 shuzu]# awk -f course.awk kecheng.datenglish 3huanjing 1chinese 4computer 1dianzi 1math 2=======================AWK中使用shell========================= [root@test740_9 shell]# cat usernumber.awk#!/bin/awk -fBEGIN{while("who"|getline) n++; #把|之前的字符串"who"送往shell执行,结果通过管道输出到awk程序print n;}[root@test740_9 shuzu]# awk 'BEGIN{"cat kecheng.dat"|getline var;print var;}'zhangsan math english chinese[root@test740_9 shuzu]#[root@test740_9 shuzu]# awk 'BEGIN{"cat kecheng.dat"|getline;print $0;}'zhangsan math english chinese[root@test740_9 shuzu]#[root@test740_9 shuzu]# awk 'BEGIN{getline var<"kecheng.dat";print var;}'zhangsan math english chinese[root@test740_9 shuzu]#[root@test740_9 shuzu]# awk 'BEGIN{getline<"kecheng.dat";print $0;}'zhangsan math english chinese[root@test740_9 shuzu]#[root@test740_9 shuzu]# awk '{getline var;print $0;print var;}' kecheng.datzhangsan math english chineselisi computer chinese englishwangwu dianzi chinese mathzhaoliu huanjing english chinese[root@test740_9 shuzu]# awk '{getline var;print var;}' kecheng.datlisi computer chinese englishzhaoliu huanjing english chinese=====================编程实例分隔符================================ awk编程实例统计上班到达时间及迟到次数.每日执行时将读入两个文件:员工当天上班时间的数据文件(arrive.dat)步骤分析:1.在上班数据文件arrive.dat 之前增加一行标题"ID Number Arrvial Time",并生产报表到文件today_result1中2.将today_result1中的数据按员工代号排序,并加注执行当日日期,输出每日报表today_result23.在today_result2每日报表中的迟到者后面加上"*",并加注当日平均到达时间,输出文件today_result3文件内容:[root@test740_9 chidao]# cat arrive.dat [root@test740_9 chidao]# cat late.datA034 7:26 A005 2A025 7:27 A006 1A101 7:32 A008 2A006 7:45 A012 0A012 7:46 A025 0A028 7:49 A028 1A051 7:51 A029 2A029 7:57 A034 0A042 7:59 A042 0A008 8:01 A051 0A052 8:05 A052 3A005 8:12 A101 01.arrive.dat 之前增加一行标题"ID Number Arrvial Time",按员工代号排序,并加注执行当日日期,输出每日报表today_result2[root@test740_9 chidao]# cat reformat2.awk#!/bin/awk -fBEGIN {"date"|getline; ##在shell中执行date指令,并将结果存储到$0中.print "Today is ",$2,$3 > "today_result2";print "ID Number Arrival Time">"today_result2";print "===========================">"today_result2";close("today_result2");}{printf("%s\t\t%s\n",$1,$2)|"sort -k 1 >> today_result2";}awk中的管道用法:a)awk output 指令| "shell 接受的命令" (如: print $1,$2 | "sort -k 1")b)"shell 接受的命令"| awk input指令(如: "ls"| getline)awk的input指令只有getline这一个输入指令awk的output指令有print, printf()两个awk另外一种调用shell命令的方法,函数system("shell 命令"):awk 'BEGIN{system("date>date.dat");getline<"date.dat";print "Today is ",$2,$3}'[root@test740_9 chidao]# cat today_result2Today is 09月03日ID Number Arrival Time===========================A005 8:12A006 7:45A008 8:01A012 7:46A025 7:27A028 7:49A029 7:57A034 7:26A042 7:59A051 7:51A052 8:05A101 7:322.以八点为上班时间,在today_result2每日报表中的迟到者后面加上"*",并加注当日平均到达时间,输出文件today_result3判断是否迟到和计算平均到达时间,将小时数和分钟数分开来算,会好算很多.我们就需要改用":"来做分隔符,进行分段. FS="[ \t:]"[root@test740_9 chidao]# cat reformat3.awk#!/bin/bashawk 'BEGIN{FS="[ \t:]";"date"|getline;print "Today is ",$2,$3 ;print "========================";print "ID Number Arrival Time";}{m=HM_TO_M($2,$3);printf ("%s\t\t%s:%s %s\n",$1,$2,$3,m>480?"*":"")|"sort -k 1"; #m>480?"*":""是个三元运算符,如果m>480就返回"*",否则"" total +=m ;}END{close("sort -k 1"); #如果不关闭会有不可预期的结果printf ("Average arrival time: %d:%d\n",total/NR/60,total/NR%60) #NR内置变量,表示执行该程序后读入的记录行数}function HM_TO_M(hour,min){return hour*60+min}' $*====================讲个交互程序的例子=====================交互程序实现输入一个英文单词,程序打印出该词对应的汉语意思,并继续等待用户输入新的英文单词。

linux中awk的用法

linux中awk的用法

linux中awk的用法(原创实用版)目录1.介绍 awk2.awk 的基本语法3.awk 的常用功能4.awk 的应用实例5.结束语正文一、介绍 awkawk 是一种文本处理工具,它可以在 Linux、Unix 和类 Unix 系统上使用。

awk 非常适合处理结构化文本数据,尤其是处理列分隔的数据。

awk 的强大之处在于它的模式匹配和文本处理能力,这使得它能够在各种场景下进行数据处理和分析。

二、awk 的基本语法awk 的基本语法包括以下几个部分:1.模式匹配:模式匹配用于定义输入文本的哪一部分需要进行处理。

例如,可以使用“$1”表示第一列,使用“$2”表示第二列,以此类推。

此外,还可以使用正则表达式进行更复杂的匹配。

2.动作:动作用于定义在匹配到特定模式时需要执行的操作。

例如,可以使用“print”命令将匹配到的内容输出,使用“sum”命令计算匹配到的数字之和,等等。

3.条件语句:awk 支持 if-else 条件语句,可以根据特定条件执行不同的动作。

4.循环结构:awk 支持 for 循环和 while 循环,可以对输入文本进行遍历或者重复执行某个动作。

5.其他:awk 还支持函数、数组等高级特性,可以根据需要进行更复杂的数据处理。

三、awk 的常用功能awk 的常用功能包括:1.字符串处理:awk 可以进行字符串匹配、替换、截取等操作。

2.数学运算:awk 可以进行加、减、乘、除等基本数学运算。

3.排序:awk 可以对输入文本进行排序,包括按行排序和按列排序。

4.文件操作:awk 可以读取多个文件,对文件内容进行处理,并将结果输出到一个或多个文件中。

四、awk 的应用实例以下是一些 awk 的应用实例:1.统计文本中每个单词出现的次数:```awk "{for (i=1; i<=NF; i++) {a[i]++}} END {for (k in a) if (a[k] > 0) print k, a[k]}" input.txt```2.将文本中的数字提取出来,并计算它们的和:```awk "{sum += $1} END {print sum}" input.txt```3.对输入文本进行排序,并输出排序后的内容:```awk "{print $1, $2, $3}" input.txt | sort -k3 | awk "{print $1, $2, $3}"```五、结束语awk 是一种功能强大的文本处理工具,适用于处理结构化文本数据。

awk命令、awk编程语言详细介绍和实例

awk命令、awk编程语言详细介绍和实例

awk命令、awk编程语⾔详细介绍和实例⼀,什么是awkawk是linux下的⼀个命令,他对其他命令的输出,对⽂件的处理都⼗分强⼤,其实他更像⼀门编程语⾔,他可以⾃定义变量,有条件语句,有循环,有数组,有正则,有函数等。

他读取输出,或者⽂件的⽅式是⼀⾏,⼀⾏的读,根据你给出的条件进⾏查找,并在找出来的⾏中进⾏操作,感觉他的设计思想,真的很简单,但是结合实际情况,具体操作起来就没有那么简单了。

他有三种形势,awk,gawk,nawk,平时所说的awk其实就是gawk。

⼆,awk中的记录,域,分割符当我们读取输出时,或者读取⽂件时,读取⼀⾏就是⼀个记录。

记录分割符是默认是回车符,保存在RS,ORS中。

我们从记录中分割出我们要单词,或者是词组等,我们称他为域,域分割符,默认的是空格和TAB銉,保存在内建变量ORS中。

举个例⼦:aaaa:bbbb:ccccccc1111:2343:5t43343上⾯有⼆⾏,这⼆⾏就是⼆个记录,每⾏后⾯的回车呢,就是记录分割符,⾥⾯冒号呢,就是域分割符,分割出来的,aaaa,1111这类东西就是域了。

awk -F: '{print $1}' testfile三,awk的内建变量和运算符1,变量变量描述$n当前记录的第n个字段,字段间由 FS分隔。

$0完整的输⼊记录。

ARGC命令⾏参数的数⽬。

ARGIND命令⾏中当前⽂件的位置(从0开始算)。

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

CONVFMT数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组。

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

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

FILENAME当前⽂件名。

FNR同 NR,但相对于当前⽂件。

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

IGNORECASE如果为真,则进⾏忽略⼤⼩写的匹配。

NF当前记录中的字段数。

NR当前记录数。

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

Linux命令高级技巧使用awk命令进行大数据文件的高效处理和分析

Linux命令高级技巧使用awk命令进行大数据文件的高效处理和分析Linux命令高级技巧:使用awk命令进行大数据文件的高效处理和分析Linux操作系统是广泛应用于服务器和大型计算机集群的一种开源操作系统。

作为开源操作系统,Linux提供了丰富的命令行工具,其中包含了许多强大的命令用于处理和分析大数据文件。

本文将介绍其中之一的awk命令,并探讨如何利用awk命令进行大数据文件的高效处理和分析。

一、awk命令简介awk是一种强大的文本处理工具,可以在Linux命令行终端中使用。

它可以根据指定的规则对输入文本进行分析,并执行相应的操作。

awk是由一系列的模式和动作组成的,其中模式用于匹配行,动作用于处理匹配到的行。

二、基本的awk命令语法awk命令的基本语法如下:```awk 'pattern { action }' inputfile```其中,pattern是用于匹配行的模式,action是对匹配到的行执行的操作,inputfile是待处理的输入文件。

下面是一个简单的例子:```awk '/keyword/ { print $0 }' inputfile```上述命令将会在inputfile文件中搜索包含关键词"keyword"的行,并将匹配到的行打印输出。

三、awk命令的高级技巧1. 指定字段分隔符在默认情况下,awk以空格作为字段的分隔符。

如果要处理以其他字符作为字段分隔符的文件,可以使用-F参数来指定分隔符。

例如,处理以逗号分隔的文件:```awk -F, '{ print $1, $2 }' inputfile```上述命令将以逗号为分隔符,将输入文件中的第一列和第二列打印输出。

2. 使用内置变量awk提供了许多内置变量,用于获取输入行的信息。

其中一些常用的内置变量包括:- $0:表示整个行- $1:表示第一个字段- NF:表示字段的数量- NR:表示当前行的行号可以使用这些内置变量来进行更复杂的处理和分析。

awk语法——精选推荐

awk语法awk是⼀个⾮常棒的数字处理⼯具。

相⽐于sed常常作⽤于⼀整⾏的处理,awk则⽐较倾向于将⼀⾏分为数个“字段”来处理。

运⾏效率⾼,⽽且代码简单,对格式化的⽂本处理能⼒超强。

先来⼀个例⼦:⽂件a,统计⽂件a的第⼀列中是浮点数的⾏的浮点数的平均值。

⽤awk来实现只需要⼀句话就可以搞定$cat a1.021 331#.ll 442.53 6ss 7awk 'BEGIN{total = 0;len = 0} {if($1~/^[0-9]+\.[0-9]*/){total += $1; len++}} END{print total/len}' a分析:$1~/^[0-9]+\.[0-9]*/表⽰1与“/ /”⾥⾯的正则表达式进⾏匹配,若匹配,则total加上1,且len⾃增,即数⽬加1.“^[0-9]+\.[0-9]*”是个正则表达式,“^[0-9]”表⽰以数字开头,“\.”是转义的意思,表⽰“.”为⼩数点的意思。

“[0-9]*”表⽰0个或多个数字)awk的⼀般语法格式为: awk [-参数变量] 'BEGIN{初始化}条件类型1{动作1}条件类型2{动作2}。

END{后处理}'其中:BEGIN和END中的语句分别在开始读取⽂件(in_file)之前和读取完⽂件之后发挥作⽤,可以理解为初始化和扫尾。

(1)参数说明: -F re:允许awk更改其字段分隔符-v var=$v 把v值赋值给var,如果有多个变量要赋值,那么就写多个-v,每个变量赋值对应⼀个-v e.g. 要打印⽂件a的第num⾏到num+num1⾏之间的⾏, awk -v num=num -v num1=num1 'NR==num,NR==num+num1{print}' a -f progfile:允许awk调⽤并执⾏progfile程序⽂件,当然progfile必须是⼀个符合awk语法的程序⽂件。

awk用法(使用入门)

awk⽤法(使⽤⼊门)awk ⽤法:awk ' pattern {action} '变量名含义ARGC 命令⾏变元个数ARGV 命令⾏变元数组FILENAME 当前输⼊⽂件名FNR 当前⽂件中的记录号FS 输⼊域分隔符,默认为⼀个空格RS 输⼊记录分隔符NF 当前记录⾥域个数NR 到⽬前为⽌记录数OFS 输出域分隔符ORS 输出记录分隔符1、awk '/101/' file 显⽰⽂件file中包含101的匹配⾏。

awk '/101/,/105/' fileawk '$1 == 5' fileawk '$1 == "CT"' file 注意必须带双引号awk '$1 * $2 >100 ' fileawk '$2 >5 && $2<=15' file2、awk '{print NR,NF,$1,$NF,}' file 显⽰⽂件file的当前记录号、域数和每⼀⾏的第⼀个和最后⼀个域。

awk '/101/ {print $1,$2 + 10}' file 显⽰⽂件file的匹配⾏的第⼀、⼆个域加10。

awk '/101/ {print $1$2}' fileawk '/101/ {print $1 $2}' file 显⽰⽂件file的匹配⾏的第⼀、⼆个域,但显⽰时域中间没有分隔符。

3、df | awk '$4>1000000 ' 通过管道符获得输⼊,如:显⽰第4个域满⾜条件的⾏。

4、awk -F "|" '{print $1}' file 按照新的分隔符“|”进⾏操作。

awk 'BEGIN { FS="[: \t|]" }{print $1,$2,$3}' file 通过设置输⼊分隔符(FS="[: \t|]")修改输⼊分隔符。

awk使用案例

查询命令: URL是/config/edit 且 处理时长大于100毫秒
awk '{ if ( $(NF-2) > 100 && $5=="/config/edit" ) print $0}' /opt/ali/config-web/backup/access_log.2018-10-*.log
登录后才能查看或发表评论立即登录或者逛逛博客园首页
awk使 用 案 例
1.输出占用率超过60%的分区
df -h | awk 'BEGIN{print "Full Partition"}NR>1{gsub("%","",$5);$5+=0;if($5>=60){print $1"\t"$5}}'
2. 停止占用8080端口的進程
lsof -i:8080 | awk 'NR!=1{print $2}' | xargs kill -sigkill
3.传入变量
# 不使用 -v参数 echo | awk 'END{print user}' user="$USER"
# 使用 -v 参数 echo | awk -v user="$USER" '{print user}' echo | awk -v user="$USER" 'END{print user}' awk -v user="$USER" 'BEGIN{print user}'
4.查询ቤተ መጻሕፍቲ ባይዱ请求 文本格式
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

通用线程通用线程::Awk Awk 实例实例实例,,第 2 2 部分部分部分记录、循环和数组 Daniel Robbins总裁兼 CEO,Gentoo Technologies, Inc. 2001 年 1 月 转载自:IBM developerWorks 中国网站 在这篇 awk 简介的续集中,Daniel Robbins 继续探索 awk(一种很棒但有怪异名称的语言)。

Daniel 将演示如何处理多行记录、使用循环结构,以及创建并使用 awk 数组。

阅读完本文后,您将精通许多 awk 的功能,而且可以编写您自己的功能强大的 awk 脚本。

多行记录多行记录 awk 是一种用于读取和处理结构化数据(如系统的 /etc/passwd 文件)的极佳工具。

/etc/passwd 是 UNIX 用户数据库,并且是用冒号定界的文本文件,它包含许多重要信息,包括所有现有用户帐户和用户标识,以及其它信息。

在我的前一篇文章中,我演示了 awk 如何轻松地分析这个文件。

我们只须将 FS(字段分隔符)变量设置成 ":"。

正确设置了 FS 变量之后,就可以将 awk 配置成分析几乎任何类型的结构化数据,只要这些数据是每行一个记录。

然而,如果要分析占据多行的记录,仅仅依靠设置 FS 是不够的。

在这些情况下,我们还需要修改 RS 记录分隔符变量。

RS 变量告诉 awk 当前记录什么时候结束,新记录什么时候开始。

譬如,让我们讨论一下如何完成处理“联邦证人保护计划”所涉及人员的地址列表的任务:Jimmy the Weasel 100 Pleasant Drive San Francisco, CA 12345 Big Tony 200Incognito Ave. Suburbia, WA 67890理论上,我们希望 awk 将每 3 行看作是一个独立的记录,而不是三个独立的记录。

如果 awk 将地址的第一行看作是第一个字段 ($1),街道地址看作是第二个字段 ($2),城市、州和邮政编码看作是第三个字段 $3,那么这个代码就会变得很简单。

以下就是我们想要得到的代码: BEGIN { FS="\n" RS="" } 在上面这段代码中,将 FS 设置成 "\n" 告诉 awk 每个字段都占据一行。

通过将 RS 设置成 "",还会告诉 awk 每个地址记录都由空白行分隔。

一旦 awk 知道是如何格式化输入的,它就可以为我们执行所有分析工作,脚本的其余部分很简单。

让我们研究一个完整的脚本,它将分析这个地址列表,并将每个记录打印在一行上,用逗号分隔每个字段。

address.awk BEGIN { FS="\n" RS="" } { print $1 ", " $2 ", " $3 }如果这个脚本保存为 address.awk,地址数据存储在文件 address.txt 中,可以通过输入 "awk -f address.awk address.txt" 来执行这个脚本。

此代码将产生以下输出:Jimmy the Weasel, 100 Pleasant Drive, San Francisco, CA 12345 Big Tony, 200 Incognito Ave., Suburbia, WA 67890OFS OFS 和和 ORS ORS在 address.awk 的 print 语句中,可以看到 awk 会连接(合并)一行中彼此相邻的字符串。

我们使用此功能在同一行上的三个字段之间插入一个逗号和空格 (", ")。

这个方法虽然有用,但比较难看。

与其在字段间插入 ", " 字符串,倒不如让通过设置一个特殊 awk 变量 OFS,让 awk 完成这件事。

请参考下面这个代码片断。

print "Hello", "there", "Jim!"这行代码中的逗号并不是实际文字字符串的一部分。

事实上,它们告诉 awk "Hello"、"there" 和 "Jim!" 是单独的字段,并且应该在每个字符串之间打印 OFS 变量。

缺省情况下,awk 产生以下输出:Hello there Jim!这是缺省情况下的输出结果,OFS 被设置成 " ",单个空格。

不过,我们可以方便地重新定义 OFS,这样 awk 将插入我们中意的字段分隔符。

以下是原始 address.awk 程序的修订版,它使用 OFS 来输出那些中间的 ", " 字符串:address.awk 的修订版BEGIN { FS="\n" RS="" OFS=", " } { print $1, $2, $3 }awk 还有一个特殊变量 ORS,全称是“输出记录分隔符”。

通过设置缺省为换行 ("\n") 的 OFS,我们可以控制在 print 语句结尾自动打印的字符。

缺省 ORS 值会使 awk 在新行中输出每个新的 print 语句。

如果想使输出的间隔翻倍,可以将 ORS 设置成 "\n\n"。

或者,如果想要用单个空格分隔记录(而不换行),将 ORS 设置成 ""。

将多行转换成用将多行转换成用 tab tab tab 分隔的格式分隔的格式分隔的格式假设我们编写了一个脚本,它将地址列表转换成每个记录一行,且用 tab 定界的格式,以便导入电子表格。

使用稍加修改的 address.awk 之后,就可以清楚地看到这个程序只适合于三行的地址。

如果 awk 遇到以下地址,将丢掉第四行,并且不打印该行: Cousin Vinnie Vinnie's Auto Shop 300 City Alley Sosueme, OR 76543 要处理这种情况,代码最好考虑每个字段的记录数量,并依次打印每个记录。

现在,代码只打印地址的前三个字段。

以下就是我们想要的一些代 码: 适合具有任意多字段的地址的 address.awk 版本BEGIN { FS="\n" RS="" ORS="" } { x=1while ( x<NF ) { print $x "\t" x++ }print $NF "\n" } 首先,将字段分隔符 FS 设置成 "\n",将记录分隔符 RS 设置成 "",这样 awk 可以象以前一样正确分析多行地址。

然后,将输出记录分隔符 ORS 设置成 "",它将使 print 语句在每个调用结尾不输出新行。

这意味着如果希望任何文本从新的一行开始,那么需要明确写入 print "\n"。

在主代码块中,创建了一个变量 x 来存储正在处理的当前字段的编号。

起初,它被设置成 1。

然后,我们使用 while 循环(一种 awk 循环结构,等同于 C 语言中的 while 循环),对于所有记录(最后一个记录除外)重复打印记录和 tab 字符。

最后,打印最后一个记录和换行;此外,由于将 ORS 设置成 "",print 将不输出换行。

程序输出如下,这正是我们所期望的:我们想要的输出。

不算漂亮,但用 tab 定界,以便于导入电子表格Jimmy the Weasel 100 Pleasant Drive San Francisco, CA 12345 Big Tony 200 Incognito Ave. Suburbia, WA 67890 Cousin Vinnie Vinnie's Auto Shop 300 City Alley Sosueme, OR 76543 循环结构循环结构 我们已经看到了 awk 的 while 循环结构,它等同于相应的 C 语言 while 循环。

awk 还有 "do...while" 循环,它在代码块结尾处对条件求值,而不象标准 while 循环那样在开始处求值。

它类似于其它语言中的 "repeat...until" 循环。

以下是一个示例: do...while do...while 示例示例示例{ count=1 do { print "I get printed at least once no matter what" } while ( count != 1 ) } 与一般的 while 循环不同,由于在代码块之后对条件求值,"do...while" 循环永远都至少执行一次。

换句话说,当第一次遇到普通 while 循环时,如果条件为假,将永远不执行该循环。

for for 循环循环循环 awk 允许创建 for 循环,它就象 while 循环,也等同于 C 语言的 for 循环: for ( initial assignment; comparison; increment ) { code block }以下是一个简短示例:for ( x = 1; x <= 4; x++ ) { print "iteration",x } 此段代码将打印:iteration 1 iteration 2 iteration 3 iteration 4 break break 和和 continue continue此外,如同 C 语言一样,awk 提供了 break 和 continue 语句。

使用这些语句可以更好地控制 awk 的循环结构。

以下是迫切需要 break 语句的代码片断: while while 死循环死循环死循环while (1) { print "forever and ever..." } 因为 1 永远代表是真,这个 while 循环将永远运行下去。

以下是一个只执行十次的循环: break break 语句示例语句示例语句示例 x=1 while(1) { print "iteration",x if ( x == 10 ) { break } x++ }这里,break 语句用于“逃出”最深层的循环。

相关文档
最新文档