vim 处理日志文件

在分析大的日志文件之前可能需要通过 vim(大的文件,可能其他文本处理工具打不开)进行一些预处理。

应用场景

删除所有匹配的行:

:g/pattern/d

删除多个 pattern(即正则表达式的或关系):

:g/pattern1\|pattern2\|pattern3/d

删除所有不匹配的行:

:g!/pattern/d

删除所有空行:

:g/^$/d

搜索 pattern 并删除前后多行,可以使用 +/-[line][command] 或者 +/-[line1],+/-[line2][command],如:

# 删除匹配的前一行
:g/pattern/-1d
# 删除匹配的后一行
:g/pattern/+1d
# 删除匹配的当前行以及前一行(其中 . 表示当前行)
:g/pattern/-1,.d
# 删除匹配的当前行以及后一行
:g/pattern/.,+1d
# 删除匹配的当前行以及前一行和后一行
:g/pattern/-1,+1d

删除指定范围(包括)内的行:

# 删除所有行
:1,$d
# 删除从第 1 行到第 200 行
:1,200d
# 删除第 100 行到当前行
:100,.d
# 删除第 100 行到当前行上一行
:100,-1d
# 删除第 100 行到当前行下一行
:100,+1d
# 删除当前行及前 5 行以及后 10 行
:-5,+10d

删除多行,如删除下面的多行数据:

CREATE SEQUENCE account_mygraph_id_seq
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;

匹配的关键是下面的 \_.,此外 \{-} 是非贪婪匹配:

:%s/^CREATE SEQUENCE\_.\{-};//

注意 % 实际上是 1,$ 的简写

全局替换(不区分是否是一个完整单词,只要匹配就进行替换):

:%s/abc/xyz

精确匹配整个单词(类似于标准正则表达式中的 \babc\b)全局替换:

:%s/\<abc\>/xyz

大小写不敏感精确匹配整个词全局替换:

:%s/\<abc\>\c/xyz

当某一行的数据量特别多,整个屏幕都放不下时,可能会期望把这一行数据单独拷贝到另一个文件,此时可以先用 vi 进行复制,然后,:e /path/to/newfile 在当前 vi 会话中打开一个新的文件,然后 p 粘贴即可。

统计文件中符合某个搜索条件的行数:

:%s/abc//n

统计当前文件总行数(包括当前所在行号):

ctrl + g

拷贝当前文件内容至另一个文件可以通过 y, p 使用默认的 clipboard,也可以通过 "[name]y, "[name]p 使用多个不同的 clipboard,如:

// v 或者 ctrl + v 切换至 visual 模式
// y 或者 "*y, "+y, "ay, "by, "cy, "1y, "2y, "3y 复制至不同的 clipboard
// 打开另外一个文件
// p 或者 "*p, "+p, "ap, "bp, "cp, "1p, "2p, "3p 选择不同的 clipboard 内容进行粘贴

注意事项

如果手工编辑或者覆盖过系统日志(CentOS 下为 /var/log/messages,Ubuntu 下为 /var/log/syslog),需要重启系统日志进程才能让日志重新生成:

# systemctl restart rsyslog
# systemctl restart systemd-journald

同时还需要注意的是,日志文件的权限会影响日志的更新,特别需要注意 SELinux 的 fcontext 属性:

# chmod 600 messages
# restorecon -F messages
# ls -l -Z messages
-rw-------. root root system_u:object_r:var_log_t:s0   messages

参考资料

vim regular expression

http://vimregex.com/

Regular Expression matching more than a single line in Vim

http://blog.vinceliu.com/2007/12/regular-expression-matching-more-than.html

Count number of matches of a pattern

http://vim.wikia.com/wiki/Count_number_of_matches_of_a_pattern

Deleting a range of n lines before and after a matched line?

https://vi.stackexchange.com/questions/3411/deleting-a-range-of-n-lines-before-and-after-a-matched-line

How can I copy text to the system clipboard from Vim?

https://vi.stackexchange.com/questions/84/how-can-i-copy-text-to-the-system-clipboard-from-vim

Sed commands

http://anaturb.net/sed.htm


最后修改于 2019-01-23