Loading

Linux - 三剑客(grep awk sed)

用一些例子加深印象,没事来翻翻。

基础正则

  • ^ 开头
  • $ 结尾
  • [] 表示区间,[^}] 表示除大括号之外的数据,到大括号就停止查找
  • * 表示 0 个或多个
  • . 表示任意字符

扩展正则

  • ? 非贪婪匹配
  • + 一个或者多个
  • () 分组
  • {} 范围约束
  • | 匹配多个表达式中的任何一个,1|3

实例

1、统计:查出日志中包含 404、500 的报错行数

# 关键字前后加空格会更佳精准过滤
$ cat tmp.log \
> | grep -E ' 404 | 500 ' \
> | wc -l
4

# ~ 与 !~ 代表是否匹配正则
$ awk '$9~/404|500/' tmp.log \
> | wc -l
4

2、找出 500 错误行的上下文请求

# A=after B=before;上下各两行
$ cat tmp.log \
> | grep -E '500' -B2 -A2

3、统计:找出访问量前三高的 IP 地址

# 请求方 IP 地址在第一列
$ awk '{print $1}' tmp.log \
> | sort | uniq -c | sort -nr \
> | head -3

4、统计:根据路径匹配获取请求数并排行

# tmp.log (简化日志)
"POST /demo/123?do=1 HTTP/2.0" 200 367 "-" "Android 10.0;" 127.0.0.1:8000
"POST /demo/456?do=2 HTTP/2.0" 200 367 "-" "Android 10.0;" 127.0.0.1:8000
"POST /demo/123/test/456?go=1 HTTP/2.0" 200 367 "-" "Android 10.0;" 127.0.0.1:8000

$ grep -E ' /demo/[0-9]{1,}' tmp1.log \
> | awk '{print $2}' 
> | sed -E 's#/demo/[0-9]*[?].*#/demo/:int:#' \
> | sed -E 's#/demo/[0-9]*/test/[0-9]*[?].*#/demo/:int:/test#' \
> | sort | uniq -c | sort -nr | head -2
 2 /demo/:int:
 1 /demo/:int:/test

5、查看当前开放的端口号和进程

$ netstat -ntpl | sed 1,2d | awk '{print $1, $4, $7}'
tcp 127.0.0.1:199 1002/snmpd
tcp 0.0.0.0:20755 26345/sshd

6、统计当前机器连接数

$ netstat -tnp \
| sed 1,2d \
| awk '{print $5}' \
| awk -F ':' '{print $1}' \
| sort | uniq -c | sort -nr 

7、统计一个进程的 CPU 和内存信息

# 使用 PS 命令统计并不准,占用内存 / 进程运行总时间
# 所以运行时间越久,CPU 占用更小,无法统计当前的真实使用率占比
$ for i in {1..20}; \
> do 
>   sleep 1; 
>   ps -o %cpu %mem -p {pid}; 
> done

# 使用 top 命令;更准确也更耗内存
# 统计 20 次,并在统计完成后打印出平均值
$ top -b -p {pid} -n 20 -d 1 \
> | grep --line-buffered {pid} \  # 逐行显示
> | awk 'BEGIN{print "cpu mem"}{print $9, $10; c+=$9; m+=$10}END{print "--------"; print c/NR, m/NR}'

# top 命令实时统计平均值; 并绘制图表
$ top -b -p {pid} -n 20 -d 1 \
> | grep --line-buffered {pid} \
> | awk 'BEGIN{OFS="\t"; print "cpu", "mem", "avgc", "avgm"}{c+=$9; m+=$10; print $9, $10, c/NR, m/NR}' \
> | gnuplot -e "set term du; plot '<cat' using 1 with lines"

# 直接在窗口展示
$ gnuplot -e "set term du; plot '<cat' using 1 with lines"
# 生成为图片
$ gnuplot -e "set term png; plot '<cat' using 1 with lines" >tmp/top.png

8、组合使用提取数据

示例:获取到用户搜索的热词后,根据分数进行排序,查找到最热门的 3 个搜索词。

// 测试数据; filename => hotWords
{
    "hotWords": [
        {"gid": 0,"score": 5562,"word": "现代都市","type": 1},
        {"gid": 0,"score": 5401,"word": "玄幻奇幻","type": 1},
        {"gid": 0,"score": 5025,"word": "宅小说","type": 1},
        {"gid": 0,"score": 4091,"word": "历史军事","type": 1},
        {"gid": 0,"score": 2666,"word": "科幻小说","type": 1}
}

组合命令如下:

$ cat hotWords \
| grep -o 'gid[^}]*}' \
| awk -F '"' '{print $4, $7}' \
| awk 'BEGIN{RS=":"; FS=","; OFS=":"}{$1=$1; print $0}' \
| sed 's/ *//' \
| grep -v '^$' \
| sort -t ':' -k2 -nr \
| head -n 3
5562: 现代都市
5401: 玄幻奇幻
5025: 宅小说
  • grep -o:过滤出数据行
  • awk -F:过滤出数据列
  • awk BEGIN:格式化数据
  • sed:去除首行空格
  • grep -v:获取除空行外的数据
  • sort:按照数字列进行排序,反序
  • head -n 3:取前三列数据
posted @ 2023-03-07 18:56  ABEELAN  阅读(40)  评论(0编辑  收藏  举报