你不得不会的awk
1、概述
- grep 文本过滤工具,逐行扫扫描匹配显示
- sed 只处理模式空间不处理源空间
- awk 只读入的文本进行切片、处理
2、awk的使用
awk [options] 'script' file1,file2,...
awk [options] 'PATTERN { action }' file1,file2,...
$0 引用被引用的整行
$1 引用第一片
...
# awk '{print $1}' 1.txt # 显示第一个字段,默认以空格分隔
# df -h | awk '{print $1}' # 显示第一个字段,默认以换行符分隔
2.1、常用符
-F :字段分隔符
# awk -F: '{print $1 $7}' /etc/passwd
NF : number of fields 当前记录字段的个数
# awk -F: '{print $1 $NF}' /etc/passwd
FS :field separator 默认是空白字符
RS :record separator 默认是换行符
# awk -v FS=: '{print $1 $NF}' /etc/passwd
OFS :output field separator 输出字段分隔符
# awk -v OFS=: '{print $1,$2}' 1.txt
2.2、printf
命令格式
printf format ,item1,item2 ...
1、与print 最大的不同是,printf需要指定format;
2、format用于指定后面的每个item的输出格式;
3、printf语句不会自动打印换行符:\n
2.3、format格式
format格式的指示符以%开头,后跟字符:
%c:显示字符的ASCII码
%d,%i: 十进制整数
%e,%E: 科学计数法显示数值
%f: 显示符点数
%g,%G: 以科学计数法的格式或浮点数的模式显示数值
%s: 显示字符串
%u:无符号整数
%%: 显示%本身
# awk '{printf "%-10s%s\n",$1,$2}' 1.txt
welcome to
how are
bye,sir.
2.4、修饰符:
N:显示宽度
-:左对齐
+:显示数字符号
2.5、输出重定向
print items > output-file
print items >> output-file
print items | command
特殊文件描述:
/dev/stdin:标准输入
/dev/stdout:标准输出
/dev/stderr:错误输出
/dev/fd/N:某特定文件描述符,如/dev/stdin 相当于/dev/fd/0
# awk -F: '{printf "%-15s%i\n",$1,$3}' /etc/passwd
# awk -F: '{printf "%-15s%i\n",$1,$3 > "/dev/stderr"}' /etc/passwd
3、awk 的操作符
3.1、算术操作符
-x:负值
+x:转换为整数
x^y,x**y:次方
x*y:相乘
x/y:除
x+Y
x-y
x%y
3.2、字符串操作符
只有一个不用写出来,用于实现字符连接
# awk 'BEGIN{print "a" "b"}'
3.3、赋值操作符
=
+=
-=
*=
/=
%=
^=
**=
==
--
# 注:如果模式为=,此时用/=/可能会用语法错误,用/[=]/
3.4、布尔值
在awk中,任何非零值或非空字符串都为真,反之就为假
3.5、比较操作符
x < y
x <= y
x > y
x >= y
x == y
x != y
x ~ y
X !~ y
~ :表示匹配模式
# awk -F: '$1 ~ /root/ {print $3,$4,$NF}' /etc/passwd
# awk -F: '$1 !~ /root/ {print $3,$4,$NF}' /etc/passwd
3.6、表达式间的逻辑关系符
&& 逻辑与
|| 逻辑或
3.7、条件表达式
selector?if-true-exp:if-false-exp
3.8、函数调用
functon_name (para1,para2)
4、awk 模式
awk 'program' input-file1 input-file2
'program ' 为
pattern { action }
pattern { action }
...
常见的模式类型:
4.1、regexp
正则表达式,模式为/regular expresson/
# awk -F: '/bash/ {print $0}' /etc/passwd
# awk -F: '/bash/ {print $1}' /etc/passwd
4.2、expresssion
表达式,其值非0或为非空字符时满足条件
如:$1 ~ /luke/ 或$1 == "1" ,运用匹配符
# awk -F: '$3 >= 500 {print $1,$3,$NF}' /etc/passwd
4.3、ranges
指定匹配范围pattern1,pattern2
4.4、BEGIN/END
特殊模式,仅在awk命令执行前运行一次或结束前运行一次
# awk -F: 'BEGIN{print"user id"}$3>=500{printf "%-10s%s\n",$1,$3}' /etc/passwd
# awk -F: 'BEGIN{print"user id"}$3>=500{printf "%-10s%s\n",$1,$3}END{print"over"}' /etc/passwd
# awk 'BEGIN{print"a""b"}'
# awk 'BEGIN{FS=":"}{print $1,$3}' /etc/passwd # BEGIN字段中赋值
4.5、empty
空模式,匹配何意字符
5、action 控制语句
5.1、if-else
语法:if (condition) {then-body} else {[ else-body ]}
# awk -F: '{if ($3==0) print $1,"admin";else print $1,"common user"}' /etc/passwd
# awk -F: '{if($3==0) printf "%-10s:%s\n",$1,"admin";else printf "%-10s:%s\n",$1,"common user"}' /etc/passwd
# awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd #赋值条件
组合例子
# awk -F: 'BEGIN{print "user id"}{if($3>=500)printf "%-10s%s\n",$1,$3}END{print "over....."}' /etc/passwd
# awk -F: 'BEGIN{print "user id"}{if($3==0)printf "%-10s%-5s%s\n",$1,$3,"admin";else printf "%-10s%-5s%s\n",$1,$3,"others"}END{print "over....."}' /etc/passwd
5.2、while
语法:while (condition){statement1;statement2;...} 将每一行切片后分别做处理,先满足条件,然后循环执行
# awk -F: '$1!~/root/{a=1;while (a<=NF) {print $a;a+=2}}' /etc/passwd # ,;两次结果不同
# awk -F: '$1!~/root/{a=1;while (a<=NF) {print $a,a+=2}}' /etc/passwd
注:print 输出换行,printf输出不换行
5.3、do-while
语法:do {statement1,statement2,...}while(condition) 先执行一遍动作再匹配条件
# awk -F: '$1!~/root/{a=1;do{print $a,a++}while(a<=NF)}' /etc/passwd
5.4、for
语法:for (varialbe assignment;condition;iteration process) {statement1,statement2,...}
# awk -F: '{for(a=1;a<=NF;a++) print $a}' /etc/passwd
5.5、case
5.6、break & continue
5.7、next
6、awk中的数组
A[b]
# awk 'BEGIN{A["x"]="nihao";A["y"]="buhao";print A["x"],A["y"]}'
# awk 'BEGIN{a="nihao";b="buhao";print a,b}'
# netstat -ant | awk '$1~/tcp/{S[$NF]++}END{for(A in S) print A ,S[A]}'
# awk -F: '$NF!~/^$/{S[$NF]++}END{for(A in S) printf "%s:%s\n",A,S[A]}' /etc/passwd
7、awk中函数
7.1、split
# netstat -ant | awk '/:50931/{split($5,B,":");IP[B[1]]++}END{for (i in IP){print IP[i],i}}' | sort -rn | head -50
8、awk 实例
求和
# awk '{sum+=$1}END{print sum}' 3.txt
求平均值
# awk '{sum+=$1}END{print sum/$NF}' 3.txt
求平和与平均值
# awk '{sum+=$1}END{print "sum =",sum,", ""everage =",sum/NR}' 4.sh
sum = 9725 , everage = 1620.83
求最大值
# awk 'BEGIN{max=0}{if($1>max)max=$1}END{print max}' 3.txt
求最小值
# awk 'BEGIN{min=19999999}{if($1<min)min=$1}END{print min}' 3.txt
访问的top10
# cat output/logs/cookie_logs/`date +%u`/cookie_log|grep -v '172.16'|grep -v '127.0.0.1' |awk -F' ' '{ if(index($1,"219.141.246")!=0) print $2; else print $1 } '|sort|uniq -c|sort -n |tail -n 10