本文共 9586 字,大约阅读时间需要 31 分钟。
第五章 gawk
5.1 什么是awk,什么是nawk,什么是gawk?
awk是Linux/UNIX下用来操纵数据和产生报告的程序语言,Nawk是新的版本,gawk是Gnu的版本。数据可以来自标准输入、一个或者多个文件,或者其他命令的输出。awk可用于命令行的简单操作,也可以写入大的应用程序。因为awk可以操纵数据,所以踏实Shell脚本和管理小型数据库中必需的工具。 awk逐行扫描文件,从第一行到最后一行,寻找匹配特定模板的行,并在这些行上运行“选择”动作。如果一个模板没有指定动作,这些匹配的行就被显示在屏幕上。如果一个动作没有模板,所有被动作指定的行都被处理。
5.1.1 awk的含义
awk分别代表其作者形式的第一个字母,它的作者是Alfred Aho、Brian Kernighan 和PeterWeinberger。
5.1.2用哪一个awk? 在很多系统中,awk被连接到正在使用的版本中,在描述awk和其特性是,我们将使用awk命令,假设它已经被连接到gawk上了,就像下面的例子一样。
5.2 awk的格式 一个awk程序包括awk命令、程序结构、引用(或输入文件)和输入文件的名字。如果输入文件没有被指定,输入就来自标准输入或键盘。
awk结构由模板、动作或者模板和动作联合组成。模板是由某种类型表达式的说明组成。如果没看见关键字if,但是你在评价表达式的时候想到了单词if,这就是模板。动作是在大括号内被分号或者新的一行分隔的一个或者多个说明。模板不能够放在大括弧中,由在斜杠中间的正则表达式和awk提供的操作中的一个或者几个组成。 格式: % awk 'pattern' filename % awk '{action}' filename % awk 'pattern {action}' filename 例如 # df| awk '$4>75000'
5.2.3 awk 命令行选项
5.3 格式输出
5.3.2 OFMT 变量 5.4 文件中的awk命令 5.5 记录和域 awk并不是把输入文件看做一个没有终止的字符串,而是看做具有一定格式和结构的。默认每一个以换行符结束的行称作一个记录。 记录分隔符 默认输入和输出的分隔符都是回车,保存在awk内建变量ORS和RS中,ORS和RS的值可以在有限的范围内修改。 $0变量 在awk中$0指的是整条记录(当发生替换或者复制而使得$0的值发生改变时,NF的值和域的个数都跟着发生改变)。换行符的值保存在awk内建变量RS中,默认情况下回车。 变量NR 多个记录的每一条都保存在内建变量NR中。每处理完一个记录,NR的值就增加1。
5.5.2 域
记录中的每一个单词称作“域”,默认情况下以空格或者tab分隔。每一个单词叫做一个域,awk跟踪域的数量,并在内建变量NF中保存这个数字。每一行的域个数是不一样的,典型限制为每行100个。可以建立新的域。
5.5.3 域分隔符
输入域分隔符 awk的内建变量FS保存输入与分隔符的值。默认值是空格或者tab。可以在BEGIN语句中或者命令行上修改FS的值。 在命令行上修改域分隔符 awk命令后面加上-F选项可以用来修改输入文件的域分隔符。在-F后面的字符串立刻变成新的饿域分隔符。包含元字符的字符串可以重新设置多个域分隔符。 使用多个域分隔符 你可以指定多个输入分隔符,若域分隔符有多个字符组成,如FS,则该字符串是一个放在方括号内的正则表达式。 输出域分隔符 默认的输出分隔符是一个空格,保存在awk的内建变量OFS中。逗号用来分隔print的域,就是OFS中的值。
5.6 模式与动作
5.6.1 模式 awk模式控制awk对输入的文件行所做的动作。一个模式包括正则表达式、条件表达式,或者二者的结合。当条件表达式为真的时候,默认动作是打印该行。当读取一个模式表达式时,可以使用if语句。使用if时不需要花括号引用。这里的if变成一个动作语句,语法结构发生了变化。 5.6.2 动作 花括号内的,用分号分隔的语句称为动作。如果模式在动作前面,模式决定什么时候发出动作。动作可以使一个语句也可以是一组语句。语句之间用分号分隔,也可以用换行符。 5.7 正则表达式 对于awk来说,正则表达式就是由斜杠之间的字符组成的模式。awk支持用正则表达式元字符修改正则表达式。 POSIX字符集 POSIX(the ProtableOperating SystemInterface)是一个用于保证程序在不同的平台之间移植的工业标准。为了便于移植,POSIX重新组织了字符集,其中包括不同国家和地区的字符、编码、用于表示现金、时间以及日期的符号等等。为了处理不同类型的字符,POSIX把表5.7中用的方括号引用的字符集的类加入了基本和扩展的正则表达式中。 例如,类[:alnum:]是A-Za-z0-9的另外一种表示方法。要使用这个类,必须将其放在另外一对方括号中,以重新组织成一个正则表达式。
5.7.1 匹配操作符
匹配操作符(~)用来在记录或者域内匹配正则表达式。
5.8 脚本文件中的awk命令
当你有多个awk的模式/动作语句的时候,最简单的办法就是把他们放在一个脚本文件中。脚本文件是一个包含awk注释和语句的文件。如果语句和动作在同一行,则必须分号分隔。若在不同的行则无需使用分号了。如果模式后面是动作,左花括号就必须与模式在同一行。 第六章 gawk功能:给表达式赋值 6.1.1比较表达式 比较表达式匹配那些只在条件为真时才运行的行。这些表达式利用关系运算符来比较数字和字符串。 <, <=, ==, !=, >=,>, ~(匹配正则表达式:x~/y/),!~(不匹配正则表达式:x!~/y/)
6.1.2 条件表达式
条件表达式使用两个符号——问号和冒号给表达式赋值。这里有一个更简洁的方法,他能实现if/else 语句一样的效果。标准格式如下: conditionalexpression1 ? expression2 : expression3 这个格式跟下面的if/else语句产生的结果是一样的 { if(expression1) expression2 else expression3 }
6.1.3 运算
运算可以在模板内进行。awk把所有的运算都作为浮点运算。 , -, *, /, %(取余),^(乘方)
6.1.4 符合模板
符合模板是用逻辑运算符连接在一起的由模板组成的表达式,且该表达式从左到右赋值。 &&, ||, !
6.1.5 范围模板
范围模板匹配从第一个模板的第一次出现到第二个模板的第一次出现,第一个模板的下一次出现到第二个模板的下一次出现等等。如果第一个模板被匹配而第二个模板没有出现,awk就显示到文件末尾的所有行。
6.1.6 数据验证程序
第七章 gawk功能:gawk编程
7.1.1 数字和字符串常量
初始化和类型强制 在awk中,变量不需要定义就可以直接使用,使用一个变量就是对变量的定义。变量的类型可以试数字、字符串,或者两者都有。在赋值的时候,等号又变表达式的类型就是变量的类型。 根据使用的不同,未初始化的变量的值为0或者空白字符串“” 强制字符串转换为数字: 强制数字转换为字符串:
所有split函数建立的域和数组元素都被认为是字符串变量,除非它值包含数字值,如果域或者数组元素为空(null),那么它们的值就是null。一个空行也被看作是一个空的字符串。
7.1.2 自定义变量
自定义变量由字母、数字和下划线组成,但是不能以数字开头。awk中的变量不需要声明。awk根据表达式中变量的内容来确定变量的类型。如果变量没有初始化,awk就初始化字符串变量的值为NULL,数值变量值为0。如果有必要,awk能把数字变量转换为字符串变量,或者相反。变量通过复制符号被赋值。 递增和递减操作符 命令行自定义变量 可以在命令行中给变量赋值,然后再把这个变量传输给awk脚本。 例如,# awk -F:-f awkscript month=4 year=2000filename 注:变量定义要在filename前面 -v选项(awk)。awk的-v选项允许BEGIN语句处理命令行参数。对于每一个从命令行传输的参数,他们前面都必须有-v选项 域变量域变量的用法类似于自定义变量,只是域变量引用的域不同。新的域可以通过赋值建立。一个域如果已被参考但是还没有赋值,它的值就是空字符串。一旦与的值改变了,就是用当前作为域分隔符的OSF的值重新计算$0变量。通常域的总数限制在100以内。 例如,# awk '$4== "CA" { $4 = "California"; print}' filename 如果第四个域的值($4)等于CA,awk就把第四个域赋值为"California"。注意,一定要有双引号,否则系统就会误认为是自定义变量而赋值为NULL. 内建变量 内建变量的名字是由大写字母组成。它们事先被赋值并可以在表达式中使用。 内建变量清单 变量名 变量内容 ARGC 命令行参数的数量 ARGIND 命令行正在处理的当前文件的AGV的索引(仅在gawk中有效) ARGV