awk文本处理
什么是awk
awk
不仅仅是一个文本处理工具,通常用于处理数据并生成结果报告- 当然
awk
也是一门编程语言,是linux
上功能最强大的数据处理工具之一
awk语法格式
- 第一种形式:
awk 'BEGIN {} pattern {commands} END {}' file_name
- 第二种形式:
standard output | awk BEGIN {} pattern {commands} END {}
- 第三种形式:
awk -f awk-script-file filenames
语法格式 | 含义 |
---|---|
BEGIN {} | 正式处理数据之前执行 |
pattern | 匹配模式,正则表达式,grep |
{commands} | 处理命令,{print $2,$3} |
END {} | 处理完所有匹配数据后执行 |
- 含义解释:
BGIN {}
发生在读文件之前,所以会在处理之前就执行了1/2{}
表示处理文件的过程,由于文件内有三行,所以会执行三次print
END {}
表示文件处理完毕后的动作
awk工作原理
awk -F : '{print $1,$3}' /etc/passwd
awk
将文件中的每一行作为输入,并将每一行赋给内部变量$0
,以换行符结束awk
开始进行字段分解,每个字段存储在已编号的变量中,从$1
开始(默认空格为分隔符)awk
默认字段分隔符是由内部变量FS
变量来确定,可以使用-F
修订awk
行处理时使用了print
函数打印分割后的字段awk
在打印后的字段加上空格,因为$1,$3
之间有一个逗号。逗号被映射至OFS
内部变量中,称为输出字段分隔符,OFS
默认为空格。awk
输出之后,将从文件中获取另一行,并将其存储在$0
中,覆盖原来的内容,然后将新的字符串分隔成字段并处理。该过程将持续到所有行处理完毕
再次解释如下:
- 读入一行文件,默认是以换行符作为读入分隔符(
RS
),读入进来后,会赋值给$0
,同时会为其编号赋值给NR
变量 - 检查
FS
变量是否有指定字段分隔符,按照字段分隔符拆分成列的形式,将每一列的内容赋值给对应的$1 $2 $3
等内部变量。同时会将分隔后的总列数赋值给NF
变量 - 输出内容,输出时候会使用
print
,$1,$3
这个逗号是输出字段分隔符,由OFS
变量控制,默认是空格 - 输出内容默认是按照换行符展示,由
ORS
控制,控制输出行分隔符,默认是换行符
awk内部变量
内置变量 | 含义 |
---|---|
$0 | 整行内容 |
$1-$n | 当前行的第1-n个字段 |
NF | 当前行的字段个数,也就是多少列 |
NR | 当前的行号,从1开始计数 |
FS | 输入字段分隔符,不指定默认以空格或tab键分隔 |
RS | 输入行分隔符,默认回车换行 |
OFS | 输出字段分隔符,默认为空格 |
ORS | 输出行分隔符,默认为回车换行 |
为了了解awk
的这些内部变量,需要准备如下数据文件进行联系。
cat awk_file.txt
ll 1990 50 51 61
kk 1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65
FS指定字段分隔符
awk
通过内置变量FS
来指定字段分隔符,默认以空格或tab
键作为分隔符
- 输出文件中的第一列
awk '{print $1}' awk_file.txt
ll
kk
hh
jj
mm
- 修改文件,然后指定多个分隔符,获取第2列内容
cat awk_file.txt
ll:1990 50 51 61
kk:1991 60 52 62
hh 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65
# 以冒号或空格为字段分隔符
awk -F '[ :]' '{print $2}' awk_file.txt
1990
1991
1992
1993
1994
- 再次修改文件
cat awk_file.txt
ll::1990 50 51 61
kk: 1991 60 52 62
hh :: 1992 70 53 63
jj 1993 80 54 64
mm 1994 90 55 65
# 连续的1个或多个冒号当一个分隔符,连续的1个或多个空格当一个分隔符来处理
awk -F '[ :]+' '{print $2}' awk_file.txt
1990
1991
1992
1993
1994
NF获取最后一列
awk
通过内置变量NF
保存每行的最后一列内容
- 通过
print
打印,NF
和$NF
,有什么不同?
$NF
提取的是最后一列
awk -F '[ :]+' '{print NF,$NF}' awk_file.txt
5 61
5 62
5 63
5 64
5 65
- 如果一个文件很长,靠数列数需要很长的时间,那如何快速打印倒数第二列
awk -F '[ :]+' '{print $(NF-1)}' awk_file.txt
51
52
53
54
55
NR获取每行行号
awk
通过内置变量NR
获取每行行号
- 使用
print
打印NR
变量,会发现NR
会记录每行文件的行号
awk '{print NR,$0}' awk_file.txt
1 ll::1990 50 51 61
2 kk: 1991 60 52 62
3 hh :: 1992 70 53 63
4 jj 1993 80 54 64
5 mm 1994 90 55 65
- 如果想打印第二行到第三行的内容
awk 'NR>1&&NR<4 {print NR,$0}' awk_file.txt
2 kk: 1991 60 52 62
3 hh :: 1992 70 53 63
# 如果想打印第三行
awk 'NR==3 {print NR,$0}' awk_file.txt
3 hh :: 1992 70 53 63
- 如果想打印第三行的第一列
awk 'NR==3 {print NR,$1}' awk_file.txt
3 hh
RS读入行分隔符
awk
通过内置变量RS
,对读入的文本进行行分隔符指定
- 准备文件内容
cat file.txt
Linux|Shell|Nginx--docker|Gitlab|jenkins--mysql|redis|mongodb
- 读入文件,并以
--
作为读入行分隔符,然后将文件拆分为三列
awk 'BEGIN {RS="--"} {print $0}' file.txt
Linux|Shell|Nginx
docker|Gitlab|jenkins
mysql|redis|mongodb
OFS输出字段分隔符
awk
内置变量OFS
,输出字段分隔符,初始情况下OFS
变量是空格
awk 'BEGIN {RS="--";FS="|";OFS=":"} {print $1,$2,$3}' file.txt
Linux:Shell:Nginx
docker:Gitlab:jenkins
mysql:redis:mongodb
ORS输出行分隔符
awk
内置变量ORS
,输出行分隔符,默认行分隔符为\n
awk 'BEGIN {RS="--";FS="|";OFS=":";ORS="==="} {print $1,$2,$3}' file.txt
Linux:Shell:Nginx===docker:Gitlab:jenkins===mysql:redis:mongodb
awk格式输出printf
awk
可以通过printf
函数生成非常漂亮的数据报表
printf语法
格式符 | 含义 |
---|---|
%s | 打印字符串 |
%d | 打印十进制数(整数) |
%f | 打印一个浮点数(小数) |
%x | 打印十六进制数 |
修饰符 | 含义 |
- | 左对齐 |
+ | 右对齐 |
printf示例
-
printf
默认没有输出行分隔符awk 'BEGIN {FS=":"} { printf $1 }' /etc/passwd rootbindaemonadmlpsyncshutdownhaltmailoperatorgames
-
加入换行,格式化输出
awk 'BEGIN {FS=":"} { printf "%s\n",$1 }' /etc/passwd root bin daemon adm lp sync shutdown halt mail operator games
-
使用占位符美化输出
awk 'BEGIN {FS=":"} { printf "%20s %20s\n",$1,$7 }' /etc/passwd root /bin/bash bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin sync /bin/sync shutdown /sbin/shutdown halt /sbin/halt mail /sbin/nologin operator /sbin/nologin games /sbin/nologin
-
默认右对齐,
-
表示左对齐awk 'BEGIN {FS=":"} { printf "%-20s %-20s\n",$1,$7 }' /etc/passwd root /bin/bash bin /sbin/nologin daemon /sbin/nologin adm /sbin/nologin lp /sbin/nologin sync /bin/sync shutdown /sbin/shutdown halt /sbin/halt mail /sbin/nologin operator /sbin/nologin games /sbin/nologin
printf实践
-
美化一个成绩表
cat student.txt oldxu 80 90 96 98 xiaowang 93 98 92 91 xiaohong 78 76 87 92 xiaoming 86 89 68 92 xiaoxiao 85 95 75 90
编写
awk
处理脚本cat student.awk BEGIN{ printf "%-10s %-10s %-10s %-10s %-10s\n","Name","Yuwen","Shuxue","Yingyu","Tiyu" } { printf "%-10s %-10d %-10d %-10d %-10d\n",$1,$2,$3,$4,$5 }
最终处理的结果
awk -f student.awk student.txt Name Yuwen Shuxue Yingyu Tiyu oldxu 80 90 96 98 xiaowang 93 98 92 91 xiaohong 78 76 87 92 xiaoming 86 89 68 92 xiaoxiao 85 95 75 90
awk模式匹配
awk
第一种模式匹配:RegExp
awk
第二种模式匹配:运算匹配、布尔值匹配、数学运算符匹配
RegExp示例
-
匹配
/etc/passwd
文件行中含有root
字符串的所有行awk 'BEGIN {FS=":"} /root/ {print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin
-
匹配
/etc/passwd
文件中以root
开头的行awk '/^root/ {print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash
-
匹配
/etc/passwd
文件中/bin/bash
结尾的行awk '/\/bin\/bash$/' /etc/passwd root:x:0:0:root:/root:/bin/bash www:x:666:666::/home/www:/bin/bash
匹配运算符示例
- 匹配运算符:
<
:小于>
:大于<=
:小于等于>=
:大于等于==
:等于!=
:不等于~
:正则匹配!~
:不匹配正则
-
以
:
为分隔符,匹配/etc/passwd
文件中第3个字段小于50的行awk 'BEGIN{FS=":"} $3<50 {print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync
-
以
:
为分隔符,匹配/etc/passwd
文件中第3个字段大于50的行awk 'BEGIN{FS=":"} $3>50 {print $0}' /etc/passwd nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin
-
以
:
为分隔符,匹配/etc/passwd
文件中第7个字段为/bin/bash
的行awk 'BEGIN{FS=":"} $7=="/bin/bash" {print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash www:x:666:666::/home/www:/bin/bash
-
以
:
为分隔符,匹配/etc/passwd
文件中第7个字段不为/bin/bash
的行awk 'BEGIN{FS=":"} $7!="/bin/bash" {print $0}' /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync
-
以
:
为分隔符,匹配/etc/passwd
文件中第3个字段包含3个数字以上的行awk 'BEGIN{FS=":"} $3 ~ /[0-9]{3,}/ {print $0}' /etc/passwd systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin chrony:x:998:996::/var/lib/chrony:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin zabbix:x:997:995:Zabbix Monitoring System:/var/lib/zabbix:/sbin/nologin nginx:x:996:994:nginx user:/var/cache/nginx:/sbin/nologin www:x:666:666::/home/www:/bin/bash
布尔运算匹配符示例
- 布尔运算:
&&
:与||
:或!
:非
-
以
:
为分隔符,匹配/etc/passwd
文件中第1个字段包含ftp
或mail
的行awk 'BEGIN{FS=":"} $1=="ftp" || $1=="mail" {print $0}' /etc/passwd mail:x:8:12:mail:/var/spool/mail:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
-
以
:
为分隔符,匹配/etc/passwd
文件中第3个字段小于50并且第4个字段大于50的行awk 'BEGIN{FS=":"} $3<50 && $4>50 {print $0}' /etc/passwd games:x:12:100:games:/usr/games:/sbin/nologin
-
以
:
为分隔符,匹配/etc/passwd
文件中没有/sbin/nologin
的行awk 'BEGIN{FS=":"} $0 !~ /\/sbin\/nologin/ {print $0}' /etc/passwd root:x:0:0:root:/root:/bin/bash sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt www:x:666:666::/home/www:/bin/bash
数学运算符匹配示例
- 加减乘除运算符:
+
:加-
:减*
:乘/
:除%
:模
-
计算学生课程分数平均值,学生课程文件内容如下:
cat student.txt oldxu 80 90 96 98 xiaowang 93 98 92 91 xiaohong 78 76 87 92 xiaoming 86 89 68 92 xiaoxiao 85 95 75 90
-
编写
awk
脚本,实现学员成绩平均值cat student2.awk BEGIN{ printf "%-10s %-10s %-10s %-10s %-10s %-10s\n","Name","Yuwen","Shuxue","Yingyu","Tiyu","AVG" } { total=$2+$3+$4+$5 avg=total/(NF-1) printf "%-10s %-10d %-10d %-10d %-10d %-10d\n",$1,$2,$3,$4,$5,avg }
-
执行脚本并观察结果
awk -f student2.awk student.txt Name Yuwen Shuxue Yingyu Tiyu AVG oldxu 80 90 96 98 91 xiaowang 93 98 92 91 93 xiaohong 78 76 87 92 83 xiaoming 86 89 68 92 83 xiaoxiao 85 95 75 90 86
awk条件判断
单分支判断
if
语句格式:{if(表达式) {语句;语句;...}}
-
以
:
为分隔符,打印当前管理员用户名称awk -F : '{ if($3==0) {print $1 " is administrator"} }' /etc/passwd root is administrator
-
以
:
为分隔符,统计系统用户数量awk -F : '{ if($3>0 && $3<1000) {i++} } END {print i}' /etc/passwd 26
-
以
:
为分隔符,统计普通用户数量awk -F : '{ if($3>1000) {i++} } END {print i}' /etc/passwd 1
-
以
:
为分隔符,只打印/etc/passwd
中第3个字段的数字在50-100范围内的行awk -F : '{ if($3>50 && $3<100) print $0 } ' /etc/passwd nobody:x:99:99:Nobody:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin
双分支判断
if...else
语句格式:
{if(表达式) {语句;语句;...}
else {语句;语句;...}}
-
以
:
为分隔符,判断第3列如果等于0,则打印该用户名称,如果不等于0则打印第7列awk 'BEGIN {FS=":"} { if ($3==0) {print $1} else {print $7} }' /etc/passwd root /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /bin/sync
-
以
:
为分隔符,判断第3列如果等于0,则打印管理员个数,否正都视为系统用户,并打印它的个数awk 'BEGIN {FS=":";OFS="\n"} { if ($3==0) {i++} else {j++} } END {print i " 个管理员",j " 个系统用户"}' /etc/passwd 1 个管理员 27 个系统用户
多分支判断
if...else if...else
语句格式:
{if(表达式) {语句;语句;...}
else if(表达式2) {语句;语句;...}
else {语句;语句;...}}
-
使用
awk if
打印当前/etc/passwd
文件管理员由多少个,系统用户多少个,普通用户多少个cat passwd_count.awk BEGIN { FS=":";OFS="\n" } { if($3==0) {i++} else if ($3>0 && $3<1001) {j++} else {k++} } END { print i " 个管理员", j " 个系统用户", k " 个普通用户" }
运行结果如下:
awk -f passwd_count.awk /etc/passwd 1 个管理员 26 个系统用户 1 个普通用户
-
打印
/etc/passwd
文件中UID
小于50、或UID
大于50小于100、或UID
大于100的用户名以及UID
cat if.awk BEGIN { FS=":" } { if ($3<50) { printf "%-20s %-20s %-10d\n","UID<50",$1,$3 } else if ($3>50 && $3<100) printf "%-20s %-20s %-10d\n","50<UID<100",$1,$3 else { printf "%-20s %-20s %-10d\n","UID>100",$1,$3 } }
运行结果如下:
awk -f if.awk /etc/passwd UID<50 root 0 UID<50 bin 1 UID<50 daemon 2 UID<50 adm 3 UID<50 lp 4 UID<50 sync 5 UID<50 shutdown 6 UID<50 halt 7 UID<50 mail 8 UID<50 operator 11 UID<50 games 12 UID<50 ftp 14 50<UID<100 nobody 99 UID>100 systemd-network 192 50<UID<100 dbus 81 UID>100 polkitd 999 50<UID<100 sshd 74 50<UID<100 postfix 89 UID>100 chrony 998 UID<50 rpc 32 UID<50 rpcuser 29 UID>100 nfsnobody 65534 UID>100 zabbix 997 UID>100 nginx 996 UID<50 apache 48 UID<50 mysql 27 UID>100 www 666 50<UID<100 tcpdump 72
-
计算下列每个同学的评价分数,并且只打印平均分数大于90的同学姓名和分数信息
cat student.txt oldxu 80 90 96 98 xiaowang 93 98 92 91 xiaohong 78 76 87 92 xiaoming 86 89 68 92 xiaoxiao 85 95 75 90
编写
awk
处理脚本cat student3.awk BEGIN{ printf "%-20s %-20s %-20s %-20s %-20s %-20s\n","Name","Chinese","English","Math","Physical","Average" } { sum=$2+$3+$4+$5 avg=sum/4 if (avg>90) { printf "%-20s %-20d %-20d %-20d %-20d %-0.2f\n",$1,$2,$3,$4,$5,avg } }
运行结果如下
awk -f student3.awk student.txt Name Chinese English Math Physical Average oldxu 80 90 96 98 91.00 xiaowang 93 98 92 91 93.50
awk循环语句
while
循环for
循环
while循环
while
循环:while
(条件表达式)动作awk 'BEGIN { i=1;while(i<=10) {print i;i++} }' 1 2 3 4 5 6 7 8 9 10 awk -F : '{ i=1;while(i<=NF) {print $i;i++} }' /etc/passwd root x 0 0 root /root /bin/bash bin x 1 1 bin /bin /sbin/nologin awk -F : '{ i=1;while(i<=2) {print $0;i++} }' /etc/passwd root:x:0:0:root:/root:/bin/bash root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin cat b.txt 111 222 333 444 555 666 777 888 999 cat b.txt | xargs -n1 111 222 333 444 555 666 777 888 999 awk '{ i=1;while(i<=NF) {print $i;i++} }' b.txt 111 222 333 444 555 666 777 888 999
for循环
for
循环:for
(初始化计数器;计数器测试:计数器变更)动作awk 'BEGIN { for(i=1;i<=5;i++) {print i} }' 1 2 3 4 5 awk -F : '{ for(i=1;i<=2;i++) {print $0} }' /etc/passwd root:x:0:0:root:/root:/bin/bash root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin bin:x:1:1:bin:/bin:/sbin/nologin awk -F : '{ for(i=1;i<=NF;i++) {print $i} }' /etc/passwd root x 0 0 root /root /bin/bash bin x 1 1 bin /bin /sbin/nologin
循环场景示例
- 需求:计算
1+2+3+4+5+...100
的和,请使用while、for
两种循环方式实现# while 循环 awk 'BEGIN { while(i=1;i<=100) { sum=i+sum;i++ } print sum }' 5050 # for 循环 awk 'BEGIN { for(i=1;i<=100;i++) { sum=i+sum } print sum }' 5050
awk数组
什么是awk数组
- 数组其实也算是变量,传统的变量只能存储一个值,但数组可以存储多个值;
- 不区分 关联数组 普通数组;
awk数组应用场景
- 通常用来统计,比如:统计网站访问
top10
、网站url
访问top10
等等
awk数组统计技巧
- 1.在
awk
中,使用数组时,不仅可以使用1 2 3 .. n
作为数组索引,也可以使用字符串作为数组索引。 - 2.要统计某个字段的值,就将该字段作为数组的索引,然后对索引进行遍历
- 统计谁就将谁作为索引的名称;
- 然后让相同索引名称的值进行自增;
- 遍历索引名称,获取对应的值,也就是次数
awk数组的语法
- 语法:
array_name[index]=value
- 示例:统计
/etc/passwd
中各种类型shell
的数量。
cat passwd_shell_count.awk
BEGIN{
FS=":"
}
# 赋值操作(因为awk是一行一行读入的,相当是循环了整个文件中的内容)
{
shell[$NF]++
}
# 赋值完成后,需要通过循环的方式将其索引的次数遍历出来
END{
for (item in shell) {
print item,shell[item]
}
}
awk -f passwd_shell_count.awk /etc/passwd
/bin/sync 1
/bin/bash 2
/sbin/nologin 23
/sbin/halt 1
/sbin/shutdown 1
- 统计主机上所有
tcp
连接状态数,按照每个tcp
状态分类
netstat -anp | grep tcp | awk '{arr[$6]++} END {for (i in arr) print i,arr[i]}'
LISTEN 8
ESTABLISHED 1
FIN_WAIT2 1
TIME_WAIT 37
awk数组示例
- 使用
awk
完成对nginx
的日志分析,
统计访问地址top10
cat nginx_top_10.awk
{
cip[$1]++
}
END {
for ( i in cip ) {
print cip[i],i
}
}
awk -f nginx_top_10.awk /var/log/nginx/access.log | sort -rn | head -10
101 10.168.99.10
5 10.168.99.14
统计访问页面top10
cat nginx_request_top10.awk
{
page[$7]++
}
END {
for ( i in page ) {
print page[i],i
}
}
awk -f nginx_request_top10.awk /var/log/nginx/access.log | sort -rn | head -10
48 /wp-admin/admin-ajax.php
8 /?cat=14
4 /
3 /wp-includes/js/admin-bar.min.js?ver=6.6.2
3 /wp-includes/css/admin-bar.min.css?ver=6.6.2
2 /wp-login.php
2 /wp-includes/js/wplink.min.js?ver=6.6.2
2 /wp-includes/js/wp-ajax-response.min.js?ver=6.6.2
2 /wp-includes/js/thickbox/thickbox.js?ver=3.1-20121105
2 /wp-includes/js/jquery/ui/sortable.min.js?ver=1.13.3
统计访问次数大于10的ip
cat nginx_top_10_2.awk
{
cip[$1]++
}
END {
for ( i in cip ) {
if (cip[i] > 10) {
print cip[i],i
}
}
}
awk -f nginx_top_10_2.awk /var/log/nginx/access.log | sort -rn | head -10
116 10.168.99.10
统计每个url访问内容总大小
# 统计每个url访问内容总大小
cat ngx_request_size.awk
{
url[$7]+=$10
count[$7]++
}
END {
for ( i in url ) {
print url[i]/1024"KB",count[i],i
}
}
awk -f ngx_request_size.awk /var/log/nginx/access.log | sort -rn
204.215KB 1 /wp-admin/edit.php
204.079KB 1 /wp-admin/post.php?post=963&action=edit
192.65KB 1 /wp-admin/post.php?post=1183&action=edit&message=1
192.115KB 1 /wp-admin/post.php?post=1183&action=edit
统计状态码为404出现的次数
cat ngx_status_404.awk
{
status[$9]++
}
END {
for ( i in status ) {
if (i == 404) {
print status[i],i
}
}
}
awk -f ngx_status_404.awk /var/log/nginx/access.log
3 404
留言