awk是一个行级文本处理工具,基本原理是逐行处理文件中的数据,查找与命令行中所给定内容进行匹配,如果发现匹配内容,则进行下一个编程步骤,如果找不到匹配内容,则继续处理下一行。
awk经过改进生成新的版本有nawk、gawk,一般linux默认为
语法格式如下:
awk ‘pattern + {action}’ filename
1)awk参数详解:
单引号‘’是为了和shell命令分开
大括号{}表示一个命令组
pattern是一个过滤器,表示匹配pattern条件的行才进行action处理
action是处理动作,常见动作为print
2)awk内置变量详解
FS:分隔符,默认是空格
OFS:输出分割符
NR:当前行数,从1开始
NF:当前记录字段数
$NF:最后一个字段
$0:当前记录
$1~$n:当前记录第几个字段(列)
3)awk内置函数
gsub(r,s):在$0中用s替换r ;awk 'gsub("root","--root--") {print}' /etc/passwd
index(s,t)返回s中第一个t的位置 awk 'n=index("hello","e") {print n}' /etc/passwd|head -n1 #2
length(s):s的长度
match(s,r):s是否匹配r
split(s,a,fs):用fs为分割符,将s分成序列 awk 'split($0,array,":") {print array[7]}' /etc/passwd|head -n1#/bin/bash
substr(s,p):返回s从p开始的子串
4)常用操作符、运算符、判断符
++ --:增加与减少(前置或后置)
^**:指数,右结合性
!+-:非、元加号、一元减号
+ - * / %:加减乘除求余
&&:逻辑与
||:逻辑或
= += -= *= /* %= ^= **=:赋值
5)流程控制语句
if(condition){}else{};
while{};
do{}while(condition);
for(init;condition;step){};
break/continue
实战
1)打印硬盘设备名称
df -h|awk '{print $1}'
2)以空格、冒号、\t、分号为分隔符,cat -T filename查看是否有\t(即符号^I)
awk -F '[ :\t;]' '{print $1}" filename
3)以冒号分割,打印第一列,同时将内容追加到awk.log中
awk -F: '{print $1 >>"awk.log"}' /etc/passwd #awk.log必须加分号
awk -F: '{print $1}' /etc/passwd >>awk.log
4)打印文件中第三至第五行,NR表示打印行号,$0表示当前处理行
awk 'NR==3,NR==5 {print $0}' /etc/passwd
awk 'NR==3,NR==5 {print}' /etc/passwd
5)打印文件中第3至第5行的行号、第一列和最后一列
awk 'NR>=3&&NR<=5 {print NR,$1,$NF}' /etc/passwd
6)打印文件中长度大于80的行号
awk 'length($0)>80{print NR}' /etc/passwd
7)引用shell变量,使用-v或双引号+单引号即可
awk -F: -v STR=hello '{print STR,$NF}' /etc/passwd
STR="hello";echo |awk '{print "' ${STR}'";}'#看不懂
8)以冒号切割,打印第一列同时只显示前5行
awk -F: 'NR>=1&&NR<=5{print $1}' /etc/passwd
head -n5 /etc/passwd|awk -F: '{print $1}'
9)指定文件第一列的总和
cat filename|awk '{sum+=$1}END{print sum}'
10)NR行号除以2余数为0则跳过改行,继续执行下一行
awk -F: '{if(NR%2!=0){print NR,$1}}' /etc/passwd
awk -F: 'NR%2==0 {next}{print NR,$1}' /etc/passwd
11)添加自定义字符
ifconfig eth0|grep netmask|awk '{print "ip_"$2}'
12)格式化输出passwd内容,printf打印字符串,%格式化输出分隔符,s表示字符类型,-12表示左对齐占用12个字符
awk -F: '{printf "%-12s%-6s%-8s\n",$1,$2,$NF}' /etc/passwd
13)OFS输出格式化\t
awk -F: '{print $1,$2,$3,$4,OFS="\t"}' /etc/passwd
netstat -an|awk '$6 ~/LISTEN/&&NR>=1&&NR<=10 {print NR,$4,$5,$6,OFS="\t"}' #看不懂,指定第六字段为LISTEN?
14)if结构语句判断大小
echo 3 2|awk '{if($1>$2){print $1,">",$2} else {print $1,"<=",$2}}'
15)使用数组总计passwd文件用户数
awk -F: 'BEGIN {count=0;} {name[count]=$1;count++};END{for(i=0;i<NR;i++)print i,name[i]}' /etc/passwd
16)分析Nginx访问日志的状态吗404、502等错误信息页面,统计次数大于20的ip地址
awk '{if($9~/502|499|500|503|404/)print $1,$9}' access.log|sort|uniq -c|sort -nr|awk '{if($1>20 print $2}'#看不懂
grep -E (502|499|500|503|404)|awk '{print $1,$9}'|sort|uniq -c|sort -nr|awk '{if($1>20 print $2}'
17)统计服务器状态连接数
netstat -an|awk '/tcp/ {s[$NF]++} END{for(a in s){print a,s[a]}}'
netstat -an|awk '/tcp/ {print $NF}'|sort|uniq -c