vim 的搜索与替换
目标
在 Vim 中使用 ex 命令过滤和替换日志文件,并把命令保存到文件,使操作可以重现。实验材料是 /opt/lab/data/app.log(480 行,格式为 IP 날짜 메서드 경로 상태코드 [ERROR])。
为什么重要
所有 ex 命令都采用范围 + 动作的结构。:%s/.../.../g、:5,20s/...、:'<,'>s/... 是同一规则的三个例子。再加上行过滤器 :g(匹配模式的行)和 :v(不匹配的行),大多数日志加工任务就都能完成。尤其要注意:如果省略 g 标志,每行只会替换第一个匹配项;而 :g 与 :v 的含义正好相反。这两点是产生静默错误结果的典型原因。
步骤
在 /root/vimp 目录中工作。.ex 文件中只写编辑命令,不要加入保存或退出命令。
- 将
/opt/lab/data/app.log复制到/root/vimp/work.log。 - 统计包含
/api/pay的行数,只把数字写入/root/vimp/count.txt。 - 将状态码为
500的最后一行的行号写入/root/vimp/last500.txt。 - 将把 IP 最后一个八位组替换为
xxx的命令保存到/root/vimp/mask.ex,结果保存到/root/vimp/masked.log。(10.1.2.3会变成10.1.2.xxx) - 将删除不含
ERROR的行的命令保存到/root/vimp/errors.ex,结果保存到/root/vimp/errors_only.log。 - 将只删除行尾为
200的行的命令保存到/root/vimp/drop200.ex,结果保存到/root/vimp/no200.log。 - 将删除第二个字段(日期)的命令保存到
/root/vimp/nodate.ex,结果保存到/root/vimp/nodate.log。 - 把同时应用上述三项变换的命令放入
/root/vimp/report.ex,结果保存到/root/vimp/report.log。最终形式为10.1.2.xxx GET /api/item 500 ERROR。
提示
:%s/패턴//gn不会修改任何内容,只会报告匹配数量。可用于替换前确认影响范围。- 反向引用会再次引用括号捕获的部分,完整匹配则用
&表示。 - 评分器会把
.ex文件重新应用到原文件副本,并检查是否与结果文件一致。 - 常见错误 1:第 5 步使用
:g会得到完全相反的结果。 - 常见错误 2:第 6 步写成
:g/200/d,会连 IP 或其他字段中包含 200 的行也删除。
创建工作副本
将 /opt/lab/data/app.log 复制到 /root/vimp/work.log。
把原文件保留为只读状态,在副本上操作是基本原则。
只统计匹配数量
统计包含 /api/pay 的行数,只把数字写入 /root/vimp/count.txt。
给替换命令加上 n 标志,就能只报告数量而不修改内容。包含斜杠的模式需要转义。
查找最后一个 500 响应
将状态码为 500 的最后一行的行号写入 /root/vimp/last500.txt。
先按 G 跳到文件末尾,再用 ? 反向搜索。当前行号可通过 Ctrl-G 或 :set number 查看。
替换并遮蔽 IP
将把 IP 最后一个八位组替换为 xxx 的命令保存到 /root/vimp/mask.ex,结果保存到 /root/vimp/masked.log。(10.1.2.3 会变成 10.1.2.xxx)
用括号捕获需要保留的部分,再通过反向引用恢复。只能更改最后一个八位组。
只保留 ERROR 行
将删除不含 ERROR 的行的命令保存到 /root/vimp/errors.ex,结果保存到 /root/vimp/errors_only.log。
:g 与 :v 的含义相反。请判断哪一个会删除不匹配的行。
删除正常响应
将只删除行尾为 200 的行的命令保存到 /root/vimp/drop200.ex,结果保存到 /root/vimp/no200.log。
如果不限定行尾,其他字段中包含 200 的行也会被匹配。
删除日期列
将删除第二个字段(日期)的命令保存到 /root/vimp/nodate.ex,结果保存到 /root/vimp/nodate.log。
捕获前两个字段后只恢复第一个字段,第二个字段就会消失。
用一个脚本完成三阶段变换
把同时应用上述三项变换的命令放入 /root/vimp/report.ex,结果保存到 /root/vimp/report.log。最终形式为 10.1.2.xxx GET /api/item 500 ERROR。
依次放入前面创建的三条命令即可。执行顺序可能影响结果,请进行确认。