1. 语法

gawk工具从命令行上指定的文件中或从标准输入获取输入,也可以与另一个程序进行交互或通过网络交换数据,除非将gawk的输出重定向,否则它将被送往标准输出。gawk命令行的语法如下:

gawk [options] [program] [file-list]
gawk [options] -f program-file [file-list]

在如上语法中,program是用户在命令行中所包含的gawk程序,program-file是存放gawk程序的文件的名称,file-list包含gawk要处理的普通文件的路径名,如果用户没有指定file-list,gawk将从标准输入获取输入或由getline或协进程指定输入。

gawk选项
全写
简写说明
--file-seperator fs-F fs将fs作为输入字段分隔符的值。
--file programe-file-f programe-file从programe-file文件中读取gawk程序。
--help-W help如何使用gawk。
--lint-W lint对不正确或不利于移植的结构发出警告。
--posix-W posix运行POSIX兼容版gawk。
--traditional-W traditional忽略gawk程序中较新的GNU特性,以保持兼容。
--assign var=value-v var=value将value赋值给变量var,可多次指定这个选项。


2. 模式和动作

gawk程序由一行或多行文本构成,其中包含一个模式和动作,格式如下:

pattern {action}

模式用来从输入中选取文本行,对于由模式选中的每行文本,gawk工具都执行动作。如果程序行中没有包含模式,gawk将选取输入中的所有行。如果程序中没有包含动作,gawk将把选中的行复制到标准输出。

用斜杠把正则表达式包装起来,就可以将其作为模式使用,"~"操作符用于测试某个字段或者变量是否匹配正则表达式,"!~"操作符用于测试不匹配。

BEGIN和END是两个独特的模式,分别是在gawk开始处理之前和处理完毕之后要执行的命令。

逗号","是范围操作符,如果在一个gawk程序行上用逗号将两个模式隔开,gawk选取从匹配第1个模式的第1行开始的文本行。gawk选取的最后一行是匹配第2个模式的那行紧接着的下一行文本。如果没有匹配第2个模式的文本行,gawk将选取直到输入末尾的所有文本行。

如果gawk匹配某个模式,它将执行gawk命令的动作部分所指定的动作。如果没有指定动作,gawk将执行默认动作,即print命令,这个动作将记录从输入复制到标准输出。

如果在print命令后面带上参数,gawk将只显示用户指定的参数,这些参数可以是变量或者字符串常量。除非用逗号将print命令中的各项区分开,否则gawk将它们连接起来。逗号使得gawk用输出字段分隔符将各项分隔开。


3. 注释和变量

gawk工具不处理以"#"号开头的程序行中的任何内容。用户可以程序注释文本前添加这个符号,这样就可以为gawk程序加入注释。

在使用gawk变量之前不需要声明变量,但用户可以选择向这些变量赋初始值,没有赋值的数值变量被初始化为0,而字符串变量则被初始化为空串。

变量
变量
含义
$0当前记录(作为单个变量)。
$1~$n当前记录中的字段。
FILENAME当前输入文件名(null表示标准输入)。
FS输入字段分隔符。
NF当前记录的字段数目。
NR当前记录的记录编号。
OFS输出字段分隔符(默认为空格符)。
ORS输出记录分隔符(默认为换行符)。
RS输入记录分隔符(默认为换行符)。


4. 函数

gawk提供一些函数来操作数字和字符串的函数。

函数
函数
含义
length(str)返回str中的字符个数,如果没参数则返回当前记录中的字符个数。
int(num)返回num的整数部分。
index(str1,str2)返回str2在str1中的位置,如果str2不存在返回0。
split(str,arr,del)用del作为定界符,将str的元素放置到数组中,返回数组元素个数。
sprintf(fmt,args)根据fmt格式化args并返回格式化后的字符串。
substr(str,pos,len)返回str中从pos开始长度为len个字符的字符串。
tolower(str)返回str的副本,但其中的所有大写字母被替换成相应的小写字母。
toupper(str)返回str的副本,但其中的所有小写字母被替换成相应的大写字母。


5. 算术操作符

下表列出的算术操作符来自C语言:

算术操作符
操作符含义
*将操作符前面的表达式与后面的表达式相乘。
/将操作符前面的表达式与后面的表达式相除。
%将操作符前面的表达式与后面的表达式相除,并取余数。
+将操作符前面的表达式与后面的表达式相加。
-将操作符前面的表达式与后面的表达式相减。
=将操作符后面的表达式的值指派给前面的变量。
++将操作符前面的变量递增。
--将操作符前面的变量递减。
+=将操作符后面的表达式与前面的表达式相加,将结果赋给前面的变量。
-=将操作符后面的表达式与前面的表达式相减,将结果赋给前面的变量。
*=将操作符后面的表达式与前面的表达式相乘,将结果赋给前面的变量。
/=将操作符后面的表达式与前面的表达式相除,将结果赋给前面的变量。
%=将操作符后面的表达式与前面的表达式相除,将余数赋给前面的变量。


6. 关联数组

关联数组使用字符串作为索引,在使用时,可以用数值字符串作为索引来模仿传统数组,语法如下:

array[string] = value

其中array为数组的名称,string为要赋值的元素的索引,value为将要指派给该元素的值。可以将特殊的for结构用于关联数组,语法如下:

for (elem in array) action


7. printf

可以用printf命令来代替print控制gawk产生的输出。gawk版的printf类似于C语言中的printf,语法如下:

printf "control-string", arg1, arg2, ..., argn

control-string决定了printf如何格式化arg1、arg2...argn。这些参数即可以是变量也可以是其他表达式。可以在control-string中使用"\n"来表示换行符,使用"\t"来表示TAB。

control-string包含了转换规格,每个参数对应一个,语法如下:

%[-][x[.y]]conv

其中,"-"使得printf将参数左对齐,"x"表示最小字段宽度,".y"表示数字中小数点右边的位置。conv指示数值转换的类型。


8. 控制结构

if...else控制结构测试由condition返回的状态,并根据该状态转移控制,语法如下:

if [condition]
  {commands}
else
  {commands}

while结构当condition为真时,遍历并执行commands,语法如下:

while (condition)
  {commands}

for结构先执行init语句,当condition为真时,循环遍历commands,每次循环之后都执行increment语句,语法如下:

for (init; condition; increment)
  {commands}

break语句将控制转移到循环之外,continue语句则将控制转移到循环的末尾。