awk是linux非常强大的报告生成工具
基本使用格式:awk [options] 'script' FILE
awk[options] '/pattern/{action}' FILE
option: -F 切割符 $0整行 $1第一列 $2第二列....
地址定界:
/pattern1/,/pattern2/ 两个正则之间的范围
/pattern/所有被匹配的行
表达式 >,>=,<,<=,==,!=,~(匹配正则)
BEGIN{}:执行前操作
END{}:收尾操作
行分隔符(输入,输出)
字段分隔符(输入,输出)
awk的内置变量:
NF:最后一个字段
FS:指定输入分割符 BEGIN中定义默认为空白
RS: Record separator,输入文本信息所使用的换行符;
OFS:指定输出分隔符 BEGIN中定义默认空白
ORS:Output Row Separator:
NR: The number of input records,awk命令所处理的记录数;如果有多个文件,这个数目会把处理的多个文件中行统一计数; NF:Number of Field,当前记录的field个数; FNR: 与NR不同的是,FNR用于记录正处理的行是当前这一文件中被总共处理的行数; ARGV: 数组,保存命令行本身这个字符串,如awk '{print $0}' a.txt b.txt这个命令中,ARGV[0]保存awk,ARGV[1]保存a.txt; ARGC: awk命令的参数的个数; FILENAME: awk命令所处理的文件的名称;在命令中获取当前文件名 ENVIRON:当前shell环境变量及其值的关联数组
awk -v 赋值变量
例: awk -v num=1 -v num=2 'BEGIN{num+num2}'
printf命令的使用格式:
printf format, item1, item2
其与print命令的最大不同是,printf需要指定format
format用于指定后面的每个item的输出格式;
printf语句不会自动打印换行符;\n
format格式的指示符都以%开头,后跟一个字符;如下: %c: 显示字符的ASCII码; %d, %i:十进制整数; %e, %E:科学计数法显示数值; %f: 显示浮点数; %g, %G: 以科学计数法的格式或浮点数的格式显示数值; %s: 显示字符串; %u: 无符号整数; %%: 显示%自身;
修饰符: N: 显示宽度; -: 左对齐; +:显示数值符号; 例: # awk -F: '{printf "%-15s %i\n",$1,$3}' /etc/passwd
操作符
-x: 负值 +x: 转换为数值; x^y: x**y: 次方 x*y: 乘法 x/y:除法 x+y: x-y: x%y:
赋值
= += -= *= /= %= ^= **= ++ --
控制语句: if-else 语法:if (condition) {then-body} else {[ else-body ]} # awk '{if ($3==0) {print $1, "Adminitrator";} else { print $1,"Common User"}}' /etc/passwd awk -F: '{if ($1=="root") print $1, "Admin"; else print $1, "Common User"}' /etc/passwd awk -F: '{if ($1=="root") printf "%-15s: %s\n", $1,"Admin"; else printf "%-15s: %s\n", $1, "Common User"}' /etc/passwd awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd
while 语法: while (condition){statement1; statment2; ...} awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd awk -F: '{i=1;while (i<=NF) { if (length($i)>=4) {print $i}; i++ }}' /etc/passwd
do-while 至少执行一次循环体,不管条件满足与否 语法: do {statement1, statement2, ...} while (condition) awk -F: '{i=1;do {print $i;i++}while(i<=3)}' /etc/passwd awk -F: '{i=4;do {print $i;i--}while(i>4)}' /etc/passwd for 语法: for ( variable assignment; condition; iteration process) { statement1, statement2, ...} awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd for in 语法: for (i in array) {statement1, statement2, ...} awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "s:%i\n",A,BASH[A]}}' /etc/passwd
case 语法:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...} break 和 continue 常用于循环或case语句中 next 提前结束对本行文本的处理,并接着处理下一行;例如,下面的命令将显示其ID号为奇数的用户: # awk -F: '{if($3%2==0) next;print $1,$3}' /etc/passwd
数组 array[index-expression] 与PHP C语法类似 索引与关联数组 要遍历数组中的每一个元素,需要使用如下的特殊结构: for (var in array) { statement1, ... } 其中,var用于引用数组下标,而不是元素值; 例: netstat -ant | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 每出现一被/^tcp/模式匹配到的行,数组S[$NF]就加1,NF为当前匹配到的行的最后一个字段,此处用其值做为数组S的元素索引; awk '{counts[$1]++}; END {for(url in counts) print counts[url], url}' /var/log/httpd/access_log 用法与上一个例子相同,用于统计某日志文件中IP地的访问量 删除数组变量 从关系数组中删除数组索引需要使用delete命令。使用格式为: delete array[index]
awk的内置函数 split(string, array [, fieldsep [, seps ] ]) 功能:将string表示的字符串以fieldsep为分隔符进行分隔,并将分隔后的结果保存至array为名的数组中;数组下标为从1开始的序列; length([string]) 功能:返回string字符串中字符的个数; substr(string, start [, length]) 功能:取string字符串中的子串,从start开始,取length个;start从1开始计数; system(command) 功能:执行系统command并将结果返回至awk命令 systime() 功能:取系统当前时间 tolower(s) 功能:将s中的所有字母转为小写
toupper(s) 功能:将s中的所有字母转为大写