awk速查手册
awk速查手册
score.txt
cat score.txt
Marry 2143 78 84 77
Jack 2321 66 78 45
Tom 2122 48 77 71
Mike 2537 87 97 95
Bob 2415 40 57 62
netstat.txt
$cat netstat.txt
Proto Recv-Q Send-Q Local-Address Foreign-Address State
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN
tcp 0 0 coolshell.cn:80 124.205.5.146:18245 TIME_WAIT
tcp 0 0 coolshell.cn:80 61.140.101.185:37538 FIN_WAIT2
tcp 0 0 coolshell.cn:80 110.194.134.189:1032 ESTABLISHED
tcp 0 0 coolshell.cn:80 123.169.124.111:49809 ESTABLISHED
tcp 0 0 coolshell.cn:80 116.234.127.77:11502 FIN_WAIT2
tcp 0 0 coolshell.cn:80 123.169.124.111:49829 ESTABLISHED
tcp 0 0 coolshell.cn:80 183.60.215.36:36970 TIME_WAIT
tcp 0 4166 coolshell.cn:80 61.148.242.38:30901 ESTABLISHED
tcp 0 1 coolshell.cn:80 124.152.181.209:26825 FIN_WAIT1
tcp 0 0 coolshell.cn:80 110.194.134.189:4796 ESTABLISHED
tcp 0 0 coolshell.cn:80 183.60.212.163:51082 TIME_WAIT
tcp 0 1 coolshell.cn:80 208.115.113.92:50601 LAST_ACK
tcp 0 0 coolshell.cn:80 123.169.124.111:49840 ESTABLISHED
tcp 0 0 coolshell.cn:80 117.136.20.85:50025 FIN_WAIT2
tcp 0 0 :::22 :::* LISTEN
1 输出
1.1 普通输出
输出第1,4列
head -4 netstat.txt | awk '{print $1, $4}'
格式化输出
head -4 netstat.txt | awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n",$1,$2,$3,$4,$5,$6}'
1.2 内建变量
变量 | 说明 |
---|---|
$0 | 当前记录(这个变量中存放着整个行的内容) |
$1~$n | 当前记录的第n个字段,字段间由FS分隔 |
FS | 输入字段分隔符 默认是空格或Tab |
NF | 当前记录中的字段个数,就是有多少列 |
NR | 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。 |
FNR | 当前记录数,与NR不同的是,这个值会是各个文件自己的行号 |
RS | 输入的记录分隔符, 默认为换行符 |
OFS | 输出字段分隔符, 默认也是空格 |
ORS | 输出的记录分隔符,默认为换行符 |
FILENAME | 当前输入文件的名字 |
输出行号
head -4 netstat.txt | awk '{print NR, $3, $6}'
1.3 指定分隔符
输出用户名、uid和shell
awk -F: '{print $1, $3, $6}' OFS='\t' /etc/passwd
# 说明
# FS输入的分隔符
# OFS输出的分隔符
指定多个分隔符
-F '[:; ]+'
# +表示多个连在一起的分隔符算一个
2 应用场景
输出第3列为0且第6列为LISTEN的行且输出表头
awk '$3==0 && $6=="LISTEN" || NR==1 {printf "%-20s %-20s %s\n",$4,$5,$6}' netstat.txt
2.1 字符串匹配
awk '$6 ~ /LISTEN/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.t
awk '/LISTEN/' netstat.txt
# 说明
~表示模式开始
/FIN/表示模式
模式取反
awk '$6 !~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
awk '!/WAIT/' netstat.txt
# 说明
!表示取反
2.2 拆分文件
awk 'NR!=1{print > $6}' netstat.txt
awk 'NR!=1{print $4,$5 > $6}' netstat.txt
# 说明
如果第6列有3种值a,b,c就会生成3个文件,每个文件是对应的行的数据
2.3 统计
计算所有C文件,CPP文件和H文件的文件大小总和
ls -l *.cpp *.c *.h | awk '{sum+=$5} END {print sum}'
统计第6列connection状态
awk 'NR!=1{a[$6]++;} END {for (i in a) print i ", " a[i];}' netstat.txt
统计每个用户的进程的占了多少内存
ps aux | awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'
2.4 使用脚本
统计学生的总分与平均分
cal.awk
$ cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
math = 0
english = 0
computer = 0
printf "NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
printf "---------------------------------------------\n"
}
#运行中
{
math+=$3
english+=$4
computer+=$5
printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
printf "---------------------------------------------\n"
printf " TOTAL:%10d %8d %8d \n", math, english, computer
printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}
执行awk脚本
awk -f cal.awk score.txt
2.5 与环境变量交互
x=5
y=10
export y
echo $x $y
awk -v val=$x '{print $1, $2, $3, $4+val, $5+ENVIRON["y"]}' OFS="\t" score.txt
2.6 几个花活
从file文件中找出长度大于80的行
awk 'length>80' file
按连接数查看客户端IP
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr
打印99乘法表
seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'