文件处理工具 AWK

参考:https://www.w3cschool.cn/awk/6d4t1k8l.html

前言-AWK是什么?有什么用?

AWK 是一种解释执行的编程语言。它非常的强大,被设计用来专门处理文本数据。AWK 的名称是由它们设计者的名字缩写而来 —— Afred Aho, Peter Weinberger 与 Brian Kernighan。

AWK 可以做非常多的工作。 下面只是其中的一小部分:

文本处理,
生成格式化的文本报告,
进行算术运算,
字符串操作,以及其它更多。

AWK基础原理

AWK 执行的流程非常简单:读( Read )、执 行( Execute )与重复( Repeat )。

  1. 读(Read) AWK 从输入流(文件、管道或者标准输入)中读入一行然后将其存入内存中。
  2. 执行(Execute) 对于每一行输入,所有的 AWK 命令按顺执行。 默认情况下,AWK 命令是针对于每一行输入,但是我们可以将其限制在指定的模式中。
  3. 重复(Repeate) 一直重复上述两个过程直到文件结束。

脚本命令程序的结构

  1. 开始块(BEGIN block)开始块的语法格式如下所示:
  2. BEGIN {awk-commands} 顾名思义,开始块就是在程序启动的时候执行的代码部分,并且它在整个过程中只执行一次。 一般情况下,我们在开始块中初始化一些变量。BEGIN 是 AWK 的关键字,因此它必须是大写的。 不过,请注意,开始块部分是可选的,你的程序可以没有开始块部分。
  3. 主体块(Body Block)主体部分的语法要求如下:
    1. /pattern/ {awk-commands} 对于每一个输入的行都会执行一次主体部分的命令。默认情况下,对于输入的每一行,AWK 都会很执行命令。但是,我们可以将其限定在指定的模式中。 注意,在主体块部分没有关键字存在。
  4. 结束块(END Block)下面是结束块的语法格式:
    1. END {awk-commands} 结束块是在程序结束时执行的代码。 END 也是 AWK 的关键字,它也必须大写。 与开始块相似,结束块也是可选的。
# 示例

先创建一个名为 marks.txt 的文件。其中包括序列号、学生名字、课程名称与所得分数。

1)    Amit     Physics    80
2)    Rahul    Maths      90
3)    Shyam    Biology    87
4)    Kedar    English    85
5)    Hari     History    89

接下来,我们将使用 AWK 脚本来显示输出文件中的内容,同时输出表头信息。

[jerry]$ awk 'BEGIN{printf "Sr No\tName\tSub\tMarks\n"} {print}' marks.txt

执行上面的代码后,将会输出如下的结果:

Sr No Name     Sub        Marks
1)    Amit     Physics    80
2)    Rahul    Maths      90
3)    Shyam    Biology    87
4)    Kedar    English    85
5)    Hari     History    89

基本语法

AWK 命令由单引号括起来:awk [options] file ...

举例: awk '{print}' marks.txt

AWK 标准选项
在命令行环境下,AWK 支持如下的标准选项:

options 是命令选项 -- 比如几个常用命令选项

  1. -F xx 以xx为分隔符,awk的默认分隔符为空格 例如 -F ':' 这样
    1. 或者分隔符紧跟在-F参数后面(中间没有空格) awk -F, '{print $2}' test.txt
  2. -f scriptfile 从脚本文件中读取awk命令 这时候就不需要后面的'script'了
  3. 第二种方式:通过指定内置变量 FS 来实现,通过-v参数,设置内置变量FS的值为,,从而达到将分隔符指定为逗号。
    1. awk -v FS="," '{print $2}' test.txt
  4. 赋值一个用户定义变量,将外部变量传递给awk -v var=value
    1. awk -v name=Jerry 'BEGIN{printf "Name = %s\n", name}' 结果Name = Jerry
  5. --dump-variables[=file] 选项;此选项会将全局变量及相应值按序输出到指定文件中。默认的输出文件名是 awkvars.out。
  6. --profile[=file] 选项。这个选项会将程序文件以一种很优美的方式输出(译注:用于格式化 awk 脚本文件)。默认输出文件是 awkprof.out
    1. 示例如下:awk --profile 'BEGIN{printf"---|Header|--\n"} {print} END{printf"---|Footer|---\n"}' marks.txt > /dev/null
    2. cat awkprof.out

其他示例


1. 统计IP访问量
awk '{print $1}' access.log | sort -n | uniq | wc -l

2. 查看某一时间段的IP访问量(4-5点)
grep"07/Apr/2017:0[4-5]" access.log | awk '{print $1}' | sort | uniq -c| sort -nr | wc -l

3. 查看访问最频繁的前100个IP
awk '{print $1}' access.log | sort -n |uniq -c | sort -rn | head -n 100

4. 查看访问100次以上的IP
awk '{print $1}' access.log | sort -n |uniq -c |awk '{if($1 >100) print $0}'|sort -rn

5. 查询某个IP的详细访问情况,按访问频率排序
grep'104.217.108.66' access.log |awk '{print $7}'|sort |uniq -c |sort -rn |head -n 100

页面访问统计
6. 查看访问最频的页面(TOP100)
awk '{print $7}' access.log | sort |uniq -c | sort -rn | head -n 100

7. 查看访问最频的页面([排除php页面】(TOP100)
grep -v ".php"  access.log | awk '{print $7}' | sort |uniq -c | sort -rn | head -n 100

8. 查看页面访问次数超过100次的页面
cat access.log | cut -d ' ' -f 7 | sort |uniq -c | awk '{if ($1 > 100) print$0}' | less

9. 查看最近1000条记录,访问量最高的页面
tail -1000 access.log |awk '{print $7}'|sort|uniq -c|sort -nr|less

10. 统计每秒的请求数,top100的时间点(精确到秒)
awk '{print $4}' access.log |cut -c14-21|sort|uniq -c|sort -nr|head -n 100

11. 统计每分钟的请求数,top100的时间点(精确到分钟)
awk '{print $4}' access.log |cut -c14-18|sort|uniq -c|sort -nr|head -n 100

12. 统计每小时的请求数,top100的时间点(精确到小时)
awk '{print $4}' access.log |cut -c14-15|sort|uniq -c|sort -nr|head -n 100


13. 在nginx log中最后一个字段加入$request_time 列出传输时间超过 3 秒的页面,显示前20条
cat access.log|awk '($NF > 3){print$7}'|sort -n|uniq -c|sort -nr|head -20

14. 列出php页面请求时间超过3秒的页面,并统计其出现的次数,显示前100条
cat access.log|awk '($NF > 1 &&  $7~/\.php/){print$7}'|sort -n|uniq -c|sort -nr|head -100

15. 统计蜘蛛抓取次数
grep'Baiduspider' access.log|wc -l

16. 统计蜘蛛抓取404的次数
grep'Baiduspider' access.log |grep'404' | wc -l

17. 查看当前TCP连接数
netstat -tan | grep"ESTABLISHED" | grep":80" | wc -l

18. 用tcpdump嗅探80端口的访问看看谁最高
tcpdump -i eth0 -tnn dst port 80 -c1000 | awk -F"." '{print$1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr



19. 按分钟统计info日志数量,取日志量最大的30个时间点
日志格式 ` [2022-11-24 14:52:10,123][pool-23-thread-1][INFO]xxxxxxxxxxxx   `
命令`grep '[INFO]' *.log | awk -v FS="[" '{print (substr($2,0,16))}' |sort|uniq -c|sort -nr|head -n 30`
解释:1. 通过FS="[" ,改变默认切分分隔符未'['  2. 通过substr切分时间,切到分钟,如2022-11-24 14:52 3. 通过sort和去重统计,再head前30名

posted @ 2022-11-25 15:13  starmoon1900  阅读(180)  评论(0编辑  收藏  举报