ot;%"后可跟以下几个常见字符:
- 格式符:
- %d,%i:十进制整数;
- %f:显示浮点数;
- %s:显示字符串;
- %u:无符号整数;
- %%:显示%自身。
- 修饰符:
- N:显示宽度;N为数值,宽度不足时若为左对齐则右边空格补足,若右对齐则左边空格补足。
- -:左对齐;
- +:显示数值正负号。
- 0:表示以0填充。
3.输入行的字段分隔符和行分隔符
使用"-F"选项或设置内置变量"FS"可以控制输入行的字段分隔符,默认分隔符为" "。可通过正则表达式指定分隔符,其实可以认为总是以正则方式指定分隔符。
以下是几个示例和需要注意的空格分隔符:
-F " "
:默认的,会压缩所有前导空白,包括制表符和空格。
-F " :"
:当空格后跟一个冒号时作为分隔符。会压缩前导空格,但不会匹配制表符,更不会压缩制表符。
-F "[ ]'
:只表示一个空格,不压缩任何空白。
-F "|"
:指定竖线作为分隔符。
-F ",[ \t]*|[ \t]+"
:逗号后跟0或多个空白,或者只有1或多个空白时作为分隔符。
也就是说,当空格写在最前面且不被中括号包围限制的时候,总会忽略前导空格,但不一定能匹配制表符。
使用内置变量"RS"可以控制输入行的行分隔符,默认为"\n",只有遇到行分隔符时才作为"一行"记录被读取。
将其读作行分隔符不标准,应该读为"记录分隔符"。例如设置以制表符作为记录分隔符。
RS="\t"
记录分隔符变量"RS"只识别第一个字符,若设置为"\t\t",则第二个"\t"被忽略。但是控制输出记录分隔符的内置变量OFS则可识别多字符。
可通过设置FS="\n";RS=""
使得awk能处理多行记录。但此时,原本的每行数据整体变成一个字段。
4.BGEIN和END
BEGIN和END是一个特殊的PATTERN,BEGIN引导的程序是在awk读取第一个文件第一行前要执行的awk程序,END引导的程序是在awk处理完最后一个文件最后一行后要执行的awk程序。通常BEGIN用于输出一个标题,或者初始化一些格式、变量等,END则用于最后的总结性输出。
所以awk稍微完整一点的格式为:
BGEIN{ACTIONS}PATTERN{ACTIONS}END{ACTIONS}
刨去BEGIN和END引导的两个程序,中间处理输入文件的程序PATTER{ACTIONS}称为"主输入循环(main input loop)"。在进入主输入循环之前,可以不用提供输入流,但进入主输入循环后,必须提供输入流。
例如,在开始处理文件前,设置输出报表的头部,在最后输出总共输出了多少行。其中print ""
表示输出一个空行。
BEGIN{print "ID NAME GENDER GENDER";print ""}{print $0}END{print "total num: " NR}
5.数组
awk的数组和shell的数组类似,都支持数值index的普通数组和字符串index的关联数组,其实数值index仍然会转换成字符串格式的index,所以awk的数组类型都是关联数组。
数组格式:array_name[index]
数值赋值:array_name[1]=value1
引用数组:array_name[1]
需要注意的是,关联数组的index必须使用双引号包围,例如array_name["ma"]
,如果写成array_name[ma]
,则表示使用变量"ma"的值作为index。若"ma"变量未定义,则这会定义一个新的数组array_name[""]
。
使用index in array_name
的方式可以判断数组array_name中是否有index下标对应的数组元素。如果有,它会返回1,否则返回0。所以判断语句可以如下:
if ( "ma" in array_name )
其实,判断某个数组变量的值是否为空也可判断该数组元素是否存在,如下。但这有副作用,当该元素不存在时,会创建它。
if ( array_name["ma"] != "" )
for循环的一种变体:
for (i in array_name){
do something about array_name[i]
}
可以用于变量数组,其中变量"i"是变量数组时的index,array_name是数组名。这是以遍历index的方式遍历数组。由于index的顺序随机,所以遍历时顺序也是随机的。当然,遍历数组的方式有多种,以上只是for循环遍历的一种方式。
使用delete语句可以删除数组中的元素或者删除整个数组。如下:
delete array_name["ma"]
delete array_name
6.流程控制语句
在ACTION中,可以使用流程控制语句。包括但不限于:
if (expression) statements
if (expression) statements else statements
while (expression) statements
for (expression; expression; expression) statements
for (expression in array) statements
do statements while (expression)
还有几个能影响循环的动作:
break:退出循环。
continue:退出当前循环,进入下一个循环
next:读入下一行,并awk程序的顶端从头开始。这个awk程序是PATTERN{action}这部分,不包括BEGIN{action}。
exit code:直接进入END,若本就在END中,则直接退出awk。如果END中的exit没有定义code,则采用前一个exit的code。
6.1 条件判断语句
if格式:
PATTERN {
if (test_cmd){
cmd1
cmd2
...
}
}
if-else格式为:
PATTERN {
if (test_cmd){
cmd1
cmd2
......
}
else
cmd3
}
当if或else结构中的命令只有一个,则其内可省大括号,如果超过一个,则需要使用大括号。
若采用一行书写格式,则如下:
PATTERN {if (test_cmd){cmd1;cmd2;...}else {cmd3;cmd4...}}
还有if-else if-else格式。
PATTERN {
if (test_cmd){cmd_list1}
else if {