根据部分行比较删除重复行

时间:2012-11-06 15:17:56

标签: vim

我有一个文本文件,其中包含数千行文字,如下所示。

123 hello world
124 foo bar
125 hello world

我想通过检查该行的子部分来测试重复项。对于上述内容,它应输出:

123 hello world
124 foo bar

是否有 vim 命令可以执行此操作?

更新:我在 windows 计算机上,因此无法使用uniq

4 个答案:

答案 0 :(得分:7)

这是一个bash命令:

sort -k2 input | uniq -s4
  • sort -k2将在排序时跳过第1个字段
  • uniq -s4将跳过前4个字符

在vim中,您可以调用上面的外部命令:

:%!sort -k2 % | uniq -s4
  • 第二个%将展开为当前文件名。

实际上,您可以使用以下命令在vim中进行排序:

:sort /^\d*\s/
  • vim将在排序时跳过匹配的数字

排序后,使用此命令删除重复的行:

:%s/\v(^\d*\s(.*)$\n)(^\d*\s\2$\n)+/\1/
  • 为了避免过多的反斜杠转义,我在模式中使用\v打开非常魔法
  • 在多行模式中,$将在换行符(\n)之前匹配位置。不过,我不认为这是必要的。
  • 你可以制作自己的正则表达式。

答案 1 :(得分:1)

使用awk:

$ awk '!a[$2$3]++' file
123 hello world
124 foo bar

进入数组时的第一个元素将count设置为1,因此进一步出现的数据不会进入数组,因为否定使得它为假。

答案 2 :(得分:1)

在VIM中,我可以使用以下命令对副本进行排序和删除

:sort u

答案 3 :(得分:0)

我不确定vim,但你可以用uniq命令做些什么。它有一个--skip-fields参数,可以用来跳过每一行的第一部分。

$ cat test.txt
123 hello world
124 foo bar
125 hello world

$ cat test.txt | sort -k 2 | uniq --skip-fields=1 | sort
123 hello world
124 foo bar