#1)从文件读取 awk 程序处理文件
echo "{print $2}" > test.awk
echo "a b c d e f" | awk -f test.awk
#2)指定分隔符,打印指定字段
#打印第二字段,默认以空格分隔:
tail -n 5 /etc/services | awk '{print $2}'
#指定冒号为分隔符打印第一字段:
tail -n 5 /etc/passwd | awk -F":" '{print $2}'
#还可以指定多个分隔符,作为同一个分隔符处理:
tail -n 5 /etc/services | awk -F"[/#]" '{print $3}'
#3)变量赋值
a=3
echo "a b c d e f g" | awk -v a=$a '{print a}'
#4)打印页眉, 打印页尾
tail -n 5 /etc/services | awk 'BEGIN{print "Server\t\tPort\t\t\tDescription\n======"}{print $0}END{print "======\nend"}'
#5)/re/正则匹配
3匹配包含 tcp 的行:
tail -n 5 /etc/services | awk '/tcp/{print $0}'
#匹配开头是 blp5 的行:
tail /etc/services | awk '^/blp5/{print $0}'
#匹配第一个字段是 8 个字符的行:
tail /etc/services | awk '$1~/\<[0-9a-z]{8}\>/{print $0}'
#6)逻辑 and、or 和 not
#匹配记录中包含 blp5 和 tcp 的行:
tail /etc/services | awk '/blp5/ && /tcp/ {print $0}'
#匹配记录中包含 blp5 或 tcp 的行:
tail /etc/services | awk '/blp5/ || /tcp/ {print $0}'
#不匹配开头是#和空行:
awk '!/^#|^$/{print $0}' /etc/httpd/conf/httpd.conf
#7)匹配范围
tail /etc/services | awk '/^blp5/,/^com/{print $0}'
#8)FS 和 OFS
awk 'BEGIN{FS=":";OFS="#"}{print $1,$2}' /etc/passwd
#9)RS 和 ORS
echo "www.baidu.com/baby/index.html" | awk 'BEGIN{RS="/"}{print $1}'
echo "www.baidu.com/baby/index.html" | awk 'BEGIN{RS="/";ORS="#"}{print $1}'
#将输出的换行符替换为+号:
echo "1 2 3 4 5 6 7 8 9" | xargs -n 1 | awk 'BEGIN{ORS="+"}{print $0}'
#替换某个字符:
echo "abcd5efgh" | awk 'BEGIN{RS="5";ORS="#"}{print $0}'
#10)打印最后一个字段:
echo "a b c d e f" | awk '{print $NF}'
#打印倒数第二个字段:
echo "a b c d e f" | awk '{print $(NF-1)}'
#排除最后两个字段:
echo "a b c d e f" | awk '{$NF="";$(NF-1)="";print $0}'
#排除第一个字段:
echo "a b c d e f" | awk '{$1="";print $0}'
#打印行数:
seq 5 | awk '{print NR}'
#打印总行数:
seq 5 | awk 'END{print NR}'
#打印第三行:
seq 5 | awk 'NR==3{print $0}'
#打印第三行第二个字段:
tail -n 5 /etc/services | awk 'NR==3{print $2}'
#打印前三行:
seq 5 | awk 'NR<=3{print $0}'
#11)&& || 逻辑 and,逻辑 or
tail /etc/services | awk '/blp5/ && /tcp/{print $0}'
tail /etc/services | awk '/blp5/ || /tcp/{print $0}'
#12)打印奇数行:
seq 10 | awk 'NR%2!=0{print $0}'
# 打印偶数行:
seq 10 | awk 'NR%2==0{print $0}'
#13)不匹配某行
seq 10 | awk 'NR!=3{print $0}'
#14)乘法和除法
seq 5 | awk '{print $1*2}'
seq 5 | awk '{print $1/2}'
#15)替换换行符为逗号:
seq 5 | awk 'BEGIN{ORS=","}{print $0}'
#16)变量赋值
字段求和:
seq 5 | awk '{sum+=$0}END{print sum}'
#17)双分支:
seq 10 | awk '{if(NR==3)print $0;else print "no"}'
#18)多分支:
seq 10 | awk '{if(NR==3)print "heihei";else if(NR==5)print "okok";else print $0}
#19)while 语句
#遍历打印所有字段:
echo "1 2 3 4 5 6 7 8 9" | xargs -n 3 | awk '{i=1;while(i<=NF){print $i;i++}}'
#20)IP 加单引号
echo "192.168.1.20 192.168.1.30" | sed -r 's/([0-9]{1,3}\.){3}[0-9]{1,3}/"&"/g'
#21)for 语句遍历数组
tail -n 10 /etc/passwd | awk -F":" '{a[i]=$1;i++}END{for(v in a)print a[v]}'
#22)通过 for 循环遍历数组
tail -n 5 /etc/passwd | awk -F":" '{a[NR]=$1}END{for(v in a)print v,a[v]}'
#23)统计相同字段出现次数
#24)分析 Nginx 日志
#统计访问 IP 次数:
awk '{IP[$1]++}END{for(v in IP)print IP[v],v}' access.log
#统计访问访问大于 100 次的 IP:
awk '{IP[$1]++}END{for(v in IP)if(IP[v]>=100)print IP[v],v}' access.log
#统计访问 IP 次数并排序取前 10:
awk '{IP[$1]++}END{for(v in IP)print IP[v],v}' access.log | sort -nr | head -n 10
#统计访问最多的 10 个页面:
awk '{INDEX[$8]++}END{for(v in INDEX)print INDEX[v],v}' access.log | head -n 10
#25)统计字符串中每个字母出现的次数:
echo "a,c,v,e,s,a,a,w,f,s,c,s,q,a,s" | awk -F"," '{for(i=1;i<=NF;i++)a[$i]++}END{for(v in a)print a[v],v}'
#26)统计平均成绩
# cat file
job 80
dave 84
tom 75
dave 73
job 72
tom 83
dave 88
awk '{a[$1]+=$2;b[$1]++}END{for(i in a)print i,a[i]/b[i]}' file