一个用vi/shell使用正则表达式进行文本处理的问题

需求如下:

输入文件input.txt:
a1
a2
a3
a4
b1
b2
a5
b3
b4
b5

要求输出文件output.txt为:
a1
a4
b1
b2
a5
b3
b5

即去掉第N行,N满足的条件是:第N行与第N-1、第N+1行的首字母都相同(不去掉首行与末行)。

请问使用vi的替换命令或shell能完成此需求吗,给点提示也行,谢谢。(我用C++已经实现了,现在就是想知道能不能用正则表达式实现)

阅读 5.4k
1 个回答

vim的正则

%s/\v((.).*\n)((\2.*\n)+)(\2.*$)/\1\5/g

分成三段解释一下

((.).*\n)
匹配第一行,外层分组用于替换的时候反向引用,内层分组用于后面判断

((\2.*\n)+)
匹配接下来 以上一行第一个字母开头的行(1行或多行)

(\2.*$)
匹配一行以第一行第一个字母开头的行

最后 \1\5 把上面匹配到的所有的行 替换成第一行和最后一行,即删除中间的行

注:最开始的\v是切换到perl正则模式,这样括号、加号就不需要转义了

BTW 这种文本处理的工作用perl脚本完成是最方便的,vi的好处是可视化调试,但是遇到大文件就GG了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题