awk速查手册

放肆的年华 提交于 2020-03-18 11:33:10

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")}'

参考

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!