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:取前三列数据