首页 >
AWK
✍ dations ◷ 2024-11-05 22:35:59 #AWK
AWK是一种优良的文本处理工具,Linux及Unix环境中现有的功能最强大的数据处理引擎之一。这种编程及数据操作语言(其名称得自于它的创始人阿尔佛雷德·艾侯、彼得·温伯格和布莱恩·柯林汉姓氏的首个字母)的最大功能取决于一个人所拥有的知识。AWK提供了极其强大的功能:可以进行正则表达式的匹配,样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上AWK的确拥有自己的语言:AWK程序设计语言,三位创建者已将它正式定义为“样式扫描和处理语言”。它允许创建简短的程序,这些程序读取输入文件、为数据排序、处理数据、对输入执行计算以及生成报表,还有无数其他的功能。gawk是AWK的GNU版本。最简单地说,AWK是一种用于处理文本的编程语言工具。AWK在很多方面类似于Unix shell编程语言,尽管AWK具有完全属于其本身的语法。它的设计思想来源于SNOBOL4、sed、Marc Rochkind设计的有效性语言、语言工具yacc和lex,当然还从C语言中获取了一些优秀的思想。在最初创造AWK时,其目的是用于文本处理,并且这种语言的基础是,只要在输入数据中有模式匹配,就执行一系列指令。该实用工具扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行。AWK是一种处理文本文件的语言。它将文件作为记录序列处理。在一般情况下,文件内容的每行都是一个记录。每行内容都会被分割成一系列的域,因此,我们可以认为一行的第一个词为第一个域,第二个词为第二个,以此类推。AWK程序是由一些处理特定模式的语句块构成的。AWK一次可以读取一个输入行。对每个输入行,AWK解释器会判断它是否符合程序中出现的各个模式,并执行符合的模式所对应的动作。AWK程序是由一系列模式--动作对组成的,写做其中pattern表示AWK在数据中查找的内容,而action是在找到匹配内容时所执行的一系列命令。输入行被分成了一些记录:记录默认由换行符分割,因此输入会按照行进行分割。程序使用给定的条件一个个的测试每条记录,并执行测试通过的条件所对应的action。pattern和action都可以省略不写。无pattern默认匹配全部的记录;而无action则是打印原始记录。简单的AWK表达式之外,pattern可以是BEGIN或END;这两种条件对应的action分别是读取所有的记录之前和之后。同时,如pattern1, pattern2的条件表示符合条件pattern1和pattern2的记录及其之间的部分。除了一般的,C语言风格的算术和逻辑运算符外,AWK允许运算符~,用来测试正则表达式是否可以与一字符串匹配。作为语法糖,没有~运算符的正则表达式会被用来对当前记录进行测试,相当于/regexp/ ~ $0。AWK命令即为前文例子中以action指代的语句。AWK命令可以包括函数调用,变量赋值,计算,及/或各项的组合。标准AWK提供了许多内建函数;其部分实现则可能提供了更多的内建函数。同时,AWK的部分实现支持动态链接库,使得其可以支持更多的函数。
便利起见,下述例子中可能省略大括号({ })。print 命令用于输出文本。其输出的文本总是以"输出记录分隔符"(Output record separator, ORS)分割的,其默认值为换行符。该命令的最简形式为:虽然域的符号($X )可能类似于某些语言中的变量(例如PHP和perl),但在AWK中,它们指代的是当前记录的域。另外,$0是指整个记录。事实上,命令print和print $0的效果是相同的。
print命令也可以显示变量、计算、函数调用的结果:其输出可以重定向到File:或重定向到管道:AWK的内建变量包括域变量,例如$1, $2, $3,以及$0。这些变量给出了记录中域的内容。
内建变量也包括一些其他变量:变量名可以是语言关键字外的,只包含大小写拉丁字母,数字和下划线(“_”)的任意字。而操作符“+ - * /”则分别代表加,减,乘,除。简单的将两个变量(或字符串常量)放在一起,则会将二者串接为一个字符串。若二者间至少有一个是常量,则中间可以不加空格;但若二者均为变量,中间必须包括空格。字符串常量是以双引号(“"”)分隔的。语句无需以分号结尾。另外,注释是以“#”开头的。函数是以与C语言类似的方式定义的,以关键字function开头,后面跟函数名称,参数列表和函数体。上面的函数可以如此调用:函数可以拥有其私有变量。其私有变量可以写在参数列表之后,因为这些值会在调用函数时被忽略。通常可以在参数列表中参数和私有变量之间加入一些空格,用以区别“真正的”参数和私有变量。
函数声明中,函数名和括号间可以有任意空格,但在调用时二者必须紧邻。AWK的hello world程序为:注意此处无需写出exit语句,因为唯一的模式是BEGIN。输出长度大于80字符的行。注意模式的默认行为是输出当前行。对输入中的单词进行计数,然后输出行数,单词数和字符数(类似wc)。由于没有提供模式,输入的全部行都可以匹配该模式,因此对每行都会执行预定操作。注意w+=NF的含义等同于w = w + NF。s是数值$NF的累加,而$NF则是每条记录中的最后一个域。NF是当前行中域的数量,例如,4。由于$4是第4个域的值,$NF,在这种情况下等于$4,则当然是最后一个域的内容。事实上,$是一个具有最高优先级的一元运算符。(若一行没有域,则有NF为0,而$0是整行:在这种情况下,要么是空串,要么只有空白符,因此其数值为0。)文件结束时,END模式得到了匹配,因此可以输出s。然而,由于可能没有输入行,此时s会没有值,从而导致没有输出。因此,对其加0可以使AWK在这种情况下对其赋值,从而得到一个数值。这种方法是将字符串强制转化为数值的惯用法(反之,与空串连接则是将数值强制转换为字符串的方法,例如s "")。如此处理之后,若程序输入为空文件,可以得到“0”作为输出,而不是一个空行。yes命令重复输入其参数(默认则是输出“y”)。在这里,我们让该命令输出“Wikipedia”。动作块则输出带行号的内容。printf函数可以模拟标准C中的printf函数,其效果与前述的print函数类似。而符合模式的行是这样产生的:NR是记录的编号,也就是AWK正在处理行的行号(从1开始)。“%”是取余数操作符。因此,NR % 4 == 1对第1,5,9等行为真。类似的,NR % 4 == 3对3,7,11等行为真。范围模式在其第一部分匹配(例如对第1行)之前为假,并在第二部分匹配(例如第3行)之前为真。然后,再在第二次匹配上其第一部分(例如第5行)前为假。sed命令则是用于截取其前7行输出,防止yes命令一直运行下去。若head命令可用的话,这行命令的效果和head -n7相同。
若范围模式的第一部分永远为真,例如设定为“1”,可以用来使该范围从输入的最开始开始。类似的,若第二部分总是为假,例如“0”,则该范围的结束即为输入的结束。
命令会输出从符合正则表达式“^--cut here--$”开始的输入行,也即从只包含“--cut here--”的行开始,直到输入的结束。使用关联数组计算词频:BEGIN块设定域分隔符为任意非字母字符。值得注意的是,分隔符不仅可以是字符串,也可以是正则表达式。然后,程序对每个输入行执行相同的操作。在此,对每个域,我们累加其小写形式出现的次数。最后,在END块中,我们输出单词及其出现的次数。代码建立了一个遍历关联数组中元素的循环,其中,i会被设为对应的键。这一点和多数语言不同,而和Objective-C 2.0中的for...in语法相似。这样的语法允许以简单的方式遍历数组,从而输出这些单词。另外,tolower函数是One True awk(见下文)的附加函数。这个程序可以以多种不同形式出现。第一个使用Bourne shell脚本来完成大部分工作。这也是最短的一个方法:awk命令中的$pattern并没有为引号所保护。在这里,模式可以检查输入行($0)是否与之匹配。FILENAME变量则包含了当前的文件名。awk没有显式的字符串连接操作符;与BASH相似,只需简单的将字符串并列即可。$0则会输出原始的输入行。
也有另外的方法来完成同样的任务。下面的脚本直接在awk中访问环境变量。这个脚本用到了数组ENVIRON,一个One True awk中引入的量。其作用类似与POSIX标准中的getenv (3)函数。这个脚本先建立了一个名为pattern的环境变量,其值为脚本的第一个参数,然后让awk在其余的参数所代表的文件内寻找该模式。
~是用于检查其两个操作数是否匹配的运算符;其逆则为!~。注意正则表达式也属于普通的字符串,可以储存于变量中。
下面的方法则采用了在命令行对变量赋值的方法,即在awk的参数中写入一个变量的值:最后,这种方法是纯awk的,无需shell的帮助,也无需知道太多关于awk脚本实现的细节(而在命令行对变量赋值的方法可能与awk的实现相关);但这种方法的脚本有点长:BEGIN块的作用不仅仅是提取出第一个参数,也防止第一个参数在BEGIN块结束后直接被解释为输入文件。ARGC,输入参数的数量永远是不小于1的,因为ARGV是执行脚本的命令名,通常是"awk"。另外,ARGV永远是空串。对于其中的if块,它表明若没有指定输入文件,awk会直接读取标准输入流(stdin)。也即也可以工作,因为程序中已经将ARGC置为了2;若该值为1,则awk会认为没有文件需要读取而直接退出。同时,若需从标准输入读取数据,需要将文件名显式的指定为-。与许多其他的程序语言相似,可以利用“shebang”语法构建自包含的awk脚本。
例如,一个名为hello.awk,可以输出“Hello, world!”的UNIX命令可以通过建立内容如下,名为hello.awk的文件来完成:-f参数告诉awk将该文件作为awk的程序文件,然后即可运行该程序。
相关
- 育空河育空河(英语:Yukon River)是北美洲主要的水系之一,发源于加拿大的育空地区(而育空地区即以发源于该地区的育空河来命名)。育空河长3,700公里,并由发源地向北流于育空-库斯科奎姆冲积
- 高尿酸血症高尿酸血症(英语:Hyperuricemia)是指血液中尿酸水平异常高的表现。在人体中,正常的尿酸浓度范围的上限是:男性400 µmol/L (6.8 mg/dL),女性360 µmol/L(6 mg/dL)。许多药物如L-多
- 有尾目有尾目(学名:Urodela)是终身有尾的两栖动物,一共有9科60属约358种,幼体与成体形态上差别不大,主要包括蝾螈、小鲵和大鲵。有尾目动物有发展完全的前肢和后肢,大小大约一致,但四肢细
- 南安普敦大学南安普敦大学(英语:University of Southampton)亦称修咸顿大学,位于英国南部港口城市南安普敦的著名研究型大学。其可追溯自1862年由亨利·罗宾逊·哈特利爵士之遗产所创办之哈
- 2006 RH1202006 RH120是一颗直径大约5米的近地小行星的临时名字 ,它通常都是绕着太阳公转,但是大约每20年左右会接近地-月系统一次。偶尔这个天体会短暂的进入临时卫星捕获(temporary sa
- 情迷索玛莉《我为玛丽狂》(英语:There's Something About Mary)是一套1998年的美国浪漫喜剧电影,由Farrelly兄弟执导,卡梅隆·迪亚兹、Matt Dillon及本·斯蒂勒主演。内容围绕着万人迷玛丽
- 再引入再引入,或称为野化放归,野放(Reintroduction),是一种经过仔细考虑后将物种重新放归大自然的一种做法。一般可从圈养、或其他地区的亚种中挑选合适的个体进行野放。这做法除了适合
- 旗后炮台坐标:22°36′47″N 120°15′52″E / 22.6131943177226°N 120.264364135353°E / 22.6131943177226; 120.264364135353旗后炮台位于高雄市旗津区之旗后山上,民国七十四年(198
- 1987年 萨格勒布第十四届夏季世界大学生运动会于1987年7月8日至7月19日在南斯拉夫社会主义联邦共和国萨格勒布举行,该届赛事共设12个大项。* 主办国家/地区(南斯拉夫)
- 维克斯-阿姆斯特朗维克斯-阿姆斯特朗有限公司是英国的一家造船公司,是由维克斯有限公司及阿姆斯特朗-惠特沃斯于1927年合并而建立的。公司大部分股份从60-70年代间国有化,其他的于1977年改组成