HJ3.1 三剑客实战 Nginx 日志分析

Linux 与 Shell 教程

操作系统历史与 Linux 与 Shell 环境搭建介绍

系统信息

Linux 常用命令

命令分类

  • 文件:everything is file
  • 进程:文件的运行形态
  • 网络:特殊的文件

文件

  • 磁盘与目录:df、ls、cd、pwd、$PWD
  • 文件编辑:交互编辑 vim、流式编辑器 sed
  • 文件权限:chmod、chown
  • 文件搜索:find
  • 文件内容:cat、more、less、grep
  • 特殊文件:软链、socket:进程通讯、管道:进程通讯

文件权限

  • ls -l 查看权限
  • 文件、目录
  • 用户、组
  • 读、写、执行、SUID、SGID
  • chmod:修改归属者
  • chgrp:修改归属组

进程

  • top
  • ps

网络

  • netstat -tlnp

  • netstat -tnp

  • mac 与 linux 不一致:netstat -p tcp -n -a

Shell Piping 管道

Shell 输入输出

  • Read 用来读取输入,并赋值给变量
  • echo , printf 可以简单输出变量
  • > file 将输出重定向到另一个文件
  • >> 表示追加 等价于 tee -a
  • < file 输入重定向
  • | 表示管道,也就是前一个命令的输出传入下一个命令的输入

文件描述符

  • 输入文件-标准输入0

  • 输出文件-标准输出1

  • 错误输出文件-标准错误2

  • 使用 2>&1 >/tmp/tmp < /tmp/tmp

文件描述符

管道

  • 把不同程序的输入和输出连接

  • 可以连接更多命令

  • 常见的组合命令 Linux 三剑客

    echo hello world | read x;echo $x
    echo hello world | {read x;echo $x;}
    echo hello world | while read x;do echo $x;done
    
管道

Linux 三剑客 grep + awk + sed

Linux 三剑客介绍

  • grep
    • global search regular expression(RE) and print out the line
    • 基于正则表达式查找满足条件的行
  • awk
    • 名字来源于三个作者的名字简称
    • 根据定位到的数据行处理其中的分段
  • sed
    • stream editor
    • 根据定位到的数据行修改数据

Linux 三剑客的价值

  • 三剑客
    • grep 数据查找定位
    • awk 数据切片
    • sed 数据修改
  • 类比 SQL
    • grep=select * from table like '%xx'
    • awk=select field from table
    • sed=update table set field=new where field=old

grep

  • grep pattern file
  • grep -i pattern file 忽略大小写
  • grep -v pattern file 不显示匹配的行
  • grep -o pattern file 把每个匹配的内容用独立的行显示
  • grep -E pattern file 使用扩展正则表达式
  • grep -A -B -C pattern file 打印命中数据的上下文
  • grep pattern -r dir / 递归搜索

pattern 正则表达式

  • 基本表达式(BRE)
    • ^ 开头 $ 结尾
    • [a-z] [0-9]区间,如果开头带有 ^ 表示不能匹配区间内的元素
    • *0个或多个
    • ·表示任意字符
  • 基本正则(BRE)与扩展正则的区别(ERE)
    • ? 非贪婪匹配
      • 一个或者多个
    • ()分组
    • {}范围约束
    • | 匹配表达式的任何一个
演练
curl https://testerhome.com | grep -o 'http://[a-zA-Z0-9\.\-]*'
curl https://testerhome.com 2>/dev/null | grep Appium | grep -v Python

awk

  • 介绍
    • Awk 是 linux 下的一个命令,同时也是一种语言解析引擎
    • Awk 具备完整的编程特性。比如执行命令,网络请求等
    • 精通 awk,是一个 linux 工作者的必备技能
  • 语法
    • awk 'pattern{action}'
awk pattern 语法
  • awk 理论上可以代替 grep
  • awk 'pattern{action}'
  • awk 'BEGIN{}END{}' 开始和结束
  • awk '/Running/' 正则匹配
  • awk '/aa/,/bb/' 区间选择
  • awk '$2~/xxx/' 字段匹配
  • awk 'NR==2' 取第二行
  • awk 'NR>1' 去掉第一行
awk 内置变量
  • PS 字段分隔符
  • OFS 输出数据的字段分隔符
  • RS 记录分隔符
  • ORS 输出字段的行分隔符
  • NF 字段数
  • NR 记录数
awk 的字段数据处理
  • -F 参数指定字段分隔符
  • BEGIN{FS="_"} 也可以表示分隔符
  • $0 代表当前的记录
  • $1 代表第一个字段
  • $N 代表第 N 个字段
  • $NF 代表最后一个字段
  • $(NF-1) 代表倒数第二个字段
awk 字段分割
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' \
| awk -F/ '{print $1,$2,$3,$4}'
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' \
| awk 'BEGIN{FS="/"}{print $1,$2,$3,$4}'
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' \
| awk 'BEGIN{FS="/|-"}{print $1,$2,$3,$4}'
  • 修改 OFS 和 ORS 让 $0 重新计算
    echo $PATH | awk 'BEGIN{FS=":";OFS=" | "}{$1=$1;print $0}'
    echo $PATH | awk 'BEGIN{RS=":";ORS="^"}{print $0}'
    
awk 行处理
  • 把单行拆为多行
    echo $PATH | awk 'BEGIN{RS=":"}{print $0}'
    echo $PATH | awk 'BEGIN{RS=":"}{print NR,$0}'
    echo $PATH | awk 'BEGIN{RS=":"}END{print NR}'
    
  • 多行组合为单行
    echo $PATH | awk 'BEGIN{RS=":"}{print $0}' |
        awk 'BEGIN{ORS=":"}{print $0}'
    
数据计算
echo '1,10
2,20
3,30' | awk 'BEGIN{a=0;FS=","}{a+=$2}END{print a/NR}'
awk 的词典结构
  • 提取包含“9期”但是并不包含“学员”的记录
    awk -F,'
    /9期/{if(member[$1]!=1) d[$1]=$0}
    /学员/{member[$1]=1;delete d[$1]}
    END{for(k in d) print d[k]}
    ' file
    

sed

  • sed [addr]X[options]
  • -e 表达式
  • sed -n '2p' 打印第二行
  • sed 's#hello#world#' 修改
  • -i 直接修改源文件
  • -E 扩展表达式
  • --debug 调试
pattern
  • 20 30,35 行数与行数范围
  • /pattern/ 正则匹配
  • //,// 正则匹配的区间,第一个表示开始命中,第二个表示结束命中,类似开闸放水
action
  • d 删除
  • p 打印,通常结合 -n 参数:sed -n '2p'
  • 查找替换:s / REGEXP / REPLACEMENT / {FLAGS}
  • 分组匹配与字段提取:sed 's#([0-9]*) | ([a-z]*)# \1 \2#'

sed

echo $PATH | awk 'BEGIN{RS=":"}{print $0}' | sed 's# / #----#g'
echo $PATH | awk 'BEGIN{RS=":"}{print $0}' | sed -n '/^\ /bin/,/sbin/p'
sed -i '.bak' -e " -e "

三剑客实战

  • 日志数据搜索
    • 找出 log 中的 404 500 的报错
      less nginx.log | awk '$9~/500|404/{print $0}'
      
    • 找出 500 错误时候的上下文 考察 grep 高级用法
      grep -B 2 " 500 " nginx.log
      
  • 日志数据统计
    • 找出访问量最高的 ip,取出 top10 统计分析
      cat nginx.log | awk '{print $1}' |sort|uniq -c|sort -nr|awk 'NR<11'|awk '{print $2}'
      
      awk '{print $1}' nginx.log | sort | uniq -c | sort -nr | head -10
      
  • 数据文件修改
    • 找出访问量最高的页面地址 借助于 sed 的统计分析
      url_summary() {
          # 管道符后面可以换行
          less nginx.log |
              awk '{print $7}' |
              # sed 的多个表达式合并
              sed -e 's/\?.*//g' \
                  -e 's/\/avatar\/[0-9]*'/\/avatar\/int/g' \
                  -e 's/\/topics\/[0-9]*/\/topics\/int/g'\
                  -e 's/\/replies\/[0-9]*/\/replies\/int/g' |
              sed -e 's/\/[0-9a-z\-]*\.png/\/id.png/g' |
              sed -e 's/\/[0-9a-z\-]*\.jpg/\/id.jpg/g' |
              sed -e 's/\/[0-9a-z\-]*\.jpeg/\/id.jpeg/g' |
              sed -e 's/\/[0-9a-z\-]*\.gif/\/id.gif/g' |
              sort | uniq -c | sort -nr
      }
      
      url_summary() {
        less /tmp/nginx.log |
          awk '{print $7,$(NF-2)}' |
          sed -e 's#/[0-9]*\.#_int_#' \
              -e 's#/[0-9]*$#/_int_#' \
              -e 's#/[a-z0-9\-]*\.#/_id_#' \
              -e 's#?[^ ]*##' \
              -e 's#/[0-9]*/#/_int_/#g' \
              -e 's#/[0-9]\{3,\} #/_int_end_ #' |
          awk '{s[$1]+=$2;n[$1]+=1}END{for(k in s) print k,s[k]/n[k]}' |
          sort -n -k2 |
          less
      }
      
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容