- awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理。
- awk有3个不同版本: awk、nawk和gawk,未作特别说明,一般指gawk,gawk是 AWK 的 GNU 版本。
- 现在一般所说的awk就是gawk
- awk程序的报告生成能力通常用来从大文本文件中提取数据元素并将它们格式化成可读的报告。最完美的例子是格式化日志文件。awk程序允许从日志文件中只过滤出你想要看的数据
- awk的基本特性之一就是它处理文本文件中数据的能力。它会自动给每行中的每个数据元素分配一个变量。
-
- $0代表整个文本行
- $1代表文本行中的第1个数据字段
- $2代表文本行中的第2个数据字段
- $n代表文本行中的第n个数据字段
- 注意:每个数据字段在文本行中都是通过字段分隔符来划分的。awk中的默认字段分隔符是任意的空白字符(例如空格或制表符)
- 如果想要读取使用其他字段分隔符的文件,可以使用-F选项指定:awk -F: '{print $1}' /etc/passwd
awk '{print $1}' hello
对hello文件中的数据,取每一行的第一列打印出来
可以将脚本写入文件script保存下来,每次直接读取文件,通过-f指定脚本文件,文件内容如下:
{
print $1
}
awk -f script hello
- 如果某编程语言一次只能执行一条命令,那么它不会有太大用处。awk编程语言允许你将多条命令组成一个正常的程序。在这我们可以把这些命令保存到一个文件中,这个文件我们就称为是awk的脚本文件。
- 格式:只要将每条命令放到一个新的行就好了,不需要用分号。
- awk -F: -f script /etc/passwd
- 这里的script是一个文件,需要使用-f参数指定 /etc/passwd是要分析的文件
- BEGIN:有时可能需要在处理数据前运行脚本,比如为报告创建开头部分。
- END:跟BEGIN关键字类似,END关键字允许你指定一个程序脚本,awk会在读完数据后执行它。
程序脚本例子:
BEGIN{
print "start..."
}
{
print "do something..."
}
END{
print "end..."
}
awk内置变量
- FS:Field Seperator, 输入时的字段分隔符
- # awk 'BEGIN{FS=":"}{print $1,$7}' /etc/passwd
- RS:Record Seperator, 输入行分隔符
- OFS: Output Field Seperator, 输出时的字段分隔符;
- ORS: Outpput Row Seperator, 输出时的行分隔符;
- NF:Numbers of Field,字段数
- NR:Numbers of Record, 行数;所有文件的一并计数;可同时处理多个文件
- FNR:行数;各文件分别计数;单个文件的行数
自定义变量使用例子:
BEGIN{
print "start..."
FS=","
RS="\n"
}
{
print "do something..."
}
END{
print "total rows:"NR
}
awk中的匹配操作符以及比较
- 正则表达式需要放在/expr/中,/expr/必须出现在它要控制的程序脚本的左花括号前。
- awk '/110.52.250.126/ {print $1}' access_2013_05_30.log 如果包含正则中的内容,打印第一个字段
- 匹配操作符允许将正则表达式限定在数据行中的特定数据字段。
- awk ' ($1 ~ /110.52.250.126/) {print $2}' access_2013_05_30.log 如果第一个字段能匹配,打印第二个字段
- awk ' ($1 !~ /110.52.250.126/) {print $2}' access_2013_05_30.log 如果第一个字段不匹配,打印第二个字段
- 扩展,
- shell中的管道|
- command 1 | command 2:他的功能是把第一个命令command 1执行的结果作为command 2的输入传给command 2
- wc -l
- 统计行数
- uniq -c
- 在输出行前面加上每行在输入文件中出现的次数
- uniq -u
- 仅显示不重复的行
- sort -nr
- -n:依照数值的大小排序
- -r:以相反的顺序来排序
- -k:按照哪一列进行排序
- -t : 指定每列分隔符
- head -3
- 取前三名
- shell中的管道|
分析论坛访问日志
首先过滤掉一些干扰数据,一些请求图片、js、css的
使用模式匹配进行过滤,默认使用空格分割之后带有url的是第7列(注意:.在模式中需要转义)
把原始数据中的资源请求地址和状态吗不是200的都过滤掉,保存到一个新的文件。
awk '($7 !~ /\.jpg|\.png|\.css|\.js|\.gif/ && $9 ~ /200/){print}' access_2013_05_30.log > clean_2013_05_30.log
统计PV、uv
pv
awk 'BEGIN{pv=0}{pv++}END {print "pv:"pv}' clean_2013_05_30.log
或者
awk '{print $0}' clean_2013_05_30.log | wc -l
uv
awk '{print $1}' clean_2013_05_30.log | sort -n | uniq -u|wc -l
注意:需要先排序再去重 这样才正确。否则uniq去重只会把挨着相等的去掉。
访问最多的前10个ip以及访问的次数
还需要使用uniq
awk '{print $1}' clean_2013_05_30.log | sort -n | uniq -c | sort -nr|head -10