转载自:http://blog.chinaunix.net/uid-23302288-id-3785105.html
感谢作者大大pspery
awk是行处理器:
相比较屏幕处理的优点,在处理庞大文件时不会出现内存溢出或是处理缓慢的问题,通常用来格式化文本信息。
awk处理过程:
依次对每一行进行处理,然后输出。
awk命令形式:
awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
[-F|-f|-v] 大参数,-F指定分隔符,-f调用脚本,-v定义变量 var=value
' ' 引用代码块
BEGIN 初始化代码块,在对每一行进行处理之前,初始化代码,主要是引用全局变量,设置FS分隔符
// 匹配代码块,可以是字符串或正则表达式
{} 命令代码块,包含一条或多条命令
; 多条命令使用分号分隔
END 结尾代码块,在对每一行进行处理之后再执行的代码块,主要是进行最终计算或输出结尾摘要信息
特殊要点:
$0 表示整个当前行
$1 每行第一个字段
NF 字段数量变量
NR 每行的记录号,多文件记录递增
FNR 与NR相似,不过多文件记录不递增,每个文件都从1开始
\t 制表符
\n 换行符
FS begin时定义分隔符
RS 输入的记录分隔符,默认为换行符(即文本是按照一行一行输入)
~ 匹配,与==相比不是精确比较
!~ 不匹配,不精确比较
== 等于,必须全部相等,精确比较
!= 不等于,精确比较
&& 逻辑与
|| 逻辑或
+ 匹配时表示一个或一个以上
/[0-9][0-9]+/ 两个或两个以上数字
/[0-9][0-9]*/ 一个或一个以上数字
FILENAME 文件名
OFS 输出字段分隔符,默认也是空格,可以改为制表符等
ORS 输出的记录分隔符
-F'[:#/]' 定义三个分隔符
打印
print是awk打印指定内容的主要命令。
awk '{print}' file 输出文件内容
awk '{print $0}' file 输出文件内容
awk '{print ""}' file 读取file的行数N,然后输出N行空格
awk '{print "a"}' /etc/passwd 读取file的行数N,然后输出N行a
awk -F" " '{print $1}' file 读取file的内容,用分隔符空格匹配,输出每行匹配到的第一个字段
awk -F" " '{print $1;print $2}' file 读取file的内容,用分隔符空格匹配,分行输出每行匹配到的前两个字段
awk -F" " '{print $1;print $2}' file 读取file的内容,用分隔符空格匹配,输出每行匹配到的前两个字段,以制表符作为分割
-f 指定脚本文件
BEGIN{
FS=" "
}
{print $1}
等同于awk -F" " '{print $1}' file
awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' file 输出空白行
ls -l| awk 'BEGIN{SUM=0}!/^d/{SUM+=$5} END{print "ths total size is ",SUM}' 计算文件总大小
-F指定分隔符
awk -F" " '{print $1}' file 读取file的内容,用分隔符空格匹配,输出每行匹配到的第一个字段
awk -F" " '{print $1 $3}' file 读取file的内容,用分隔符空格匹配,输出每行匹配到的第一个及第三个字段,相连输出
awk -F" " '{print $1,$3}' file 读取file的内容,用分隔符空格匹配,输出每行匹配到的第一个及第三个字段,空格连接输出
awk -F" " '{print "firstword:"$1 "\t\tthirdword:" $3}' file 自定义格式化输出
awk -F" " '{print NF}' file 打印每行有多少字段
awk -F" " '{print $NF}' file 打印每行第NF个字段
awk '{print NR}' file 打印行号
awk -F" " '{print NR,NF,$NF,'\t',$0}' file 依次打印 行号,字段数,最后一个字段,制表符,整行内容
匹配代码块
//纯字符匹配 !//纯字符不匹配 ~//字段值匹配 !~//字段值不匹配 ~/a1|a2/字段值匹配a1或a2
awk '/name/' file
awk '/name/{print}' file
awk '/name/{print $0}' file 此三条命令结果一致,匹配含有name的行
上述三条命令/name/变为!/name/,则匹配不包含name的行
awk '/miaomiao|wangwang/' file 可用|进行或运算,匹配miaomiao或wangwang,同样加!表示匹配不包含的行
awk -F" " '/miaomiao/,/wangwang/' file 匹配包含喵喵及旺旺的整个区间
awk -F“ ” '$1~/my/{print $1}' file 第一个字段为my时,显示第一个字段
加!表示第一个字段不为my时。
if语句
if必须要用在{}中,且内容要用()括起来。
awk -F" " '{if($1~/my/) print $1}' file 如果第一个字段为my则输出
awk -F" " '{if($1~/my/) {print $1} else {print $2}}' file 如果第一个字段为my则输出,否则输出第二个字段
awk -F" " '{if($1~/my/) next; else {print $0}}' file 如果匹配到my则跳过,否则输出整行。
while循环
awk 'BEGIN{i=1}{while(i<NF) print NF,i++}' file i=1,当i<=NF时,输出NF,i,然后i+1,直到i>NF,退出循环
条件表达式
== != > >= < <=
准备文件
依次运用上述符号
逻辑运算符
&& ||
awk -F" " '$1~/my/ && $5~/miaomiao/ {print $0}' file 匹配第一个字段为my且第五个字段为miaomiao的,输出整句
awk -F" " '$1~/my/ || $5~/miaomiao/ {print $0}' file 匹配第一个字段为my或第五个字段为miaomiao的,输出整句
数值运算
加,减,乘,除,取整
输出处理结果到文件
在命令代码块中直接输出
使用重定向进行输出
格式化输出
netstat -anp|awk '{printf "%-8s %-8s %-10s\n",$1,$2,$3}'
printf表示格式输出
%格式化输出分隔符
-8长度为8个字符
s表示字符串类型
打印每行前三个字段,指定第一个字段输出字符串类型(长度为8),第二个字段输出字符串类型(长度为8),
第三个字段输出字符串类型(长度为10)
数组
netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) print i,"\t",a[i]}'