RS,ORS,FS,OFS,NR,NF,$0,$n
RS 输入的行分隔号
ORS 输出的行分隔号
FS 输入的列分隔号
OFS 输出的列分隔号
NR 行号
NF 尾列号
$0 表示所有列(整行)
$n 表示第n列
例如:
shell> cat aa
1 2
3 4
5 6
shell> awk 'BEGIN{ORS=",\n"}{print}' aa
1 2,
3 4,
5 6,
RS反之
shell> awk 'BEGIN{ORS=",\n"}{print}' aa | awk 'BEGIN{RS=",\n"}{print}'
1 2
3 4
5 6
shell> awk 'BEGIN{OFS="|"}{print $1,$2}'
1|2
3|4
5|6
FS反之
shell> awk 'BEGIN{OFS="|"}{print $1,$2}' | awk 'BEGIN{FS="|"}{print $1,$2}'
1 2
3 4
5 6
备注:
shell> ifconfig | awk -F "[ |:]+" 'NR==2 {print $4}'
等同于
shell> ifconfig | awk 'BEGIN{FS="[ |:]+"};NR==2 {print $4}'
运算符号
和shell相同
加+,减-,乘*,除/,求余%
逻辑符号
等于==,不等于!=,大于>,小于<,大于等于>=,小于等于<=,匹配~,不匹配!~
扩展逻辑运算符
与&&,或||,非!,括号()
awk -F ':' '{print $1,$2}' aa
-F参数,后面跟列分隔符号,默认是空格或者制表符
-F ":"等同于FS=":"
例如
ifconfig | awk -F "[ |:]+" 'NR==2 {print $4}'
等同于 ifconfig | awk 'BEGIN{FS="[ |:]+"} NR==2 {print $4}'
BEGIN和END
BEGIN即在正常输出的最上方添加输出或定义值
END是在正常输出的最下方添加输出
例如:
shell> seq 3 | awk 'BEGIN {print "计算总和",total=0} {total=total+$0;{print $0}} END
{printf "total=%-5s\n",total}'
结果是
计算总和 0 ##BEGIN输出
1
2
3
total=6 ##END输出
if流程控制(判断语句)
{if () ...else ...}
例如:
shell> seq 3 | awk 'BEGIN {print "奇数求和";total=0} {if ($1%2!=0) {print \
$1;total=total+$1} else {print $1}}END{printf "oddtotal=%-5s\n",total}'
奇数求和
1
2
3
oddtotal=4
循环
while语句
{while()...}
例如:
shell> seq 3 | awk '{i=1;while(i<=2){print $0,i;i++}}'
1 1
1 2
2 1
2 2
3 1
3 2
shell> seq 9| awk '{i=1;while(i<=$0){print i,"x",$0,"=",$0*i;i++}}'
1 x 1 = 1
1 x 2 = 2
...
9 x 9 = 81
do...while语句
{do...while()}
这个语句感觉比较绕口,乍一看,以为是shell until的翻版,实际不是那么回事,还是
while语句,只是条件放到了最后。
例如:
shell> seq 3 | awk '{i=2;do {print i,$0;i--} while (i!=0)}'
2 1
1 1
2 2
1 2
2 3
1 3
for语句
{for () ...}
shell> seq 3 | awk '{for (i=1;i<=2;i++) {print i,$0}}'
1 1
2 1
1 2
2 2
1 3
2 3
break和continue,awk 也支持循环中断控制命令
等同于shell的break和continue
break跳出循环,执行循环的下一句
continue是跳出本次循环,执行循环的第一句
{
for ((i=1;i<=3;i++))
do
echo $i
if [ i = 2 ]
then
break
fi
done
echo 4
}
##这是一个shell脚本依次将break换成continue,exit和 ":" 就能看出来区别了
":"的输出是
1 2 3 4
continue输出是
1 3 4
break输出是
1 4
exit输出是
1
awk算术运算符
运算符用途
------------------
x^y x的y次幂
x**y 同上
x%y 计算x/y的余数(求模)
x+y x加y
x-y x减y
x*y x乘y
x/y x除y
-y 负y(y的开关符号);也称一目减
++y y加1后使用y(前置加)
y++ 使用y值后加1(后缀加)
--y y减1后使用y(前置减)
y-- 使用后y减1(后缀减)
x=y 将y的值赋给x
x+=y 将x+y的值赋给x
x-=y 将x-y的值赋给x
x*=y 将x*y的值赋给x
x/=y 将x/y的值赋给x x%=y 将x%y的值赋给x
x^=y 将x^y的值赋给x
x**=y 将x**y的值赋给x
操作符
x==y x等于y
x!=y x不等于y
x>y x大于y
x>=y x大于或等于y
x<y x小于y
x<=y x小于或等于y
x~re x匹配正则表达式re
x!~re x不匹配正则表达式re?
awk的操作符(按优先级升序排列)
= 、+=、 -=、 *= 、/= 、 %=
||
&&
> >= < <= == != ~ !~
xy (字符串连结,'x'y'变成"xy")
+ -
* / %
++ --
数组
这个和shell差不多,区别是awk数组从1开始计数,shell是从0开始计数
V 函数用途或返回值
------------------------------------------------
N gsub(reg,string,target) 每次常规表达式reg匹配时替换target中的string
N index(search,string) 返回string中search串的位置
A length(string) 求串string中的字符个数
N match(string,reg) 返回常规表达式reg匹配的string中的位置
N printf(format,variable) 格式化输出,按format提供的格式输出变量variable。
N split(string,store,delim) 根据分界符delim,分解string为store的数组元素
N sprintf(format,variable) 返回一个包含基于format的格式化数据,variables是要放到
串中的数据
G strftime(format,timestamp) 返回一个基于format的日期或者时间串,timestmp是
systime()函数返回的时间
N sub(reg,string,target) 第一次当常规表达式reg匹配,替换target串中的字符串
A substr(string,position,len) 返回一个以position开始len个字符的子串
P totower(string) 返回string中对应的小写字符
P toupper(string) 返回string中对应的大写字符
A atan(x,y) x的余切(弧度)
N cos(x) x的余弦(弧度)
A exp(x) e的x幂
A int(x) x的整数部分
A log(x) x的自然对数值
N rand() 0-1之间的随机数
N sin(x) x的正弦(弧度)
A sqrt(x) x的平方根
A srand(x) 初始化随机数发生器。如果忽略x,则使用system()
G system() 返回自1970年1月1日以来经过的时间(按秒计算)
V 变量含义缺省值
--------------------------------------------------------
N ARGC 命令行参数个数
G ARGIND 当前被处理文件的ARGV标志符
N ARGV 命令行参数数组
G CONVFMT 数字转换格式 %.6g
P ENVIRON UNIX环境变量
N ERRNO UNIX系统错误消息
G FIELDWIDTHS 输入字段宽度的空白分隔字符串
A FILENAME 当前输入文件的名字
P FNR 当前记录数
A FS 输入字段分隔符空格
G IGNORECASE 控制大小写敏感0(大小写敏感)
A NF 当前记录中的字段个数
A NR 已经读出的记录数
A OFMT 数字的输出格式 %.6g
A OFS 输出字段分隔符空格
A ORS 输出的记录分隔符新行
A RS 输入的记录他隔符新行
N RSTART 被匹配函数匹配的字符串首
N RLENGTH 被匹配函数匹配的字符串长度
N SUBSEP 下标分隔符 "34"
附:printf简单说明
printf "%-3s,%.2f,%.2d\n" abcd 3.1415 1
abcd,3.14,01
% 匹配对应位的值,后面跟格式
%-ns 打印占n个字符,不足空格补齐,超出以实际字符数为准
%.nf 打印小数点后n位,超出部分四舍五入,不足补零
%.nd 打印数值占用n个字符数,不足补零,超出以实际数字为准
\n 换行
\t 制表符
%% %
附:综合实例
计算某文件夹下某种文件的总大小
shell> ls -Rl /var/log | grep "\.log$" | awk 'BEGIN {OFS="\t";print "行号","文件名","大小";total=0} {if( $5 !=\ 0 ){print NR,$9,$5;total=total+$5} else {printf "null\n"}} END {printf "\nTotal Size: %.2fM\n",total/1024/1024}'
行号 文件名 大小
1 auth.log 2557
2 daemon.log 106
3 emerge.log 3288
null
null
null
null
8 net-snmpd.log 181
null
10 syslog-ng.log 6242
11 user.log 1758
null
13 mysql.log 2870741
14 summary.log 3894
Total Size: 2.75M