10

我正在寻找一个更具体的:sort u命令版本,它允许从文件中删除所有重复的行。我正在使用 CSV 文件,并希望删除在其第二列条目中具有重复项的所有行。换句话说,如果两行在第二列中具有相同的值,则它们被声明为重复。

例如,对于以下文件:

a,1,b
g,1,f
c,1,x
i,2,l
m,1,k
o,2,p
u,1,z

有问题的命令应该产生:

a,1,b
i,2,l

选择要保留的特定行并不重要,只要第二列条目都是唯一的。

什么 Vim 命令会产生上面的输出?

谢谢!

4

3 回答 3

13

由于不可能在一次:sort命令运行中实现所讨论的转换,因此让我们将其视为一个两步过程。

1.第一步是按第二列的值对行进行排序(用逗号与第一列分隔)。为此,我们可以使用该:sort命令,传递与第一列和以下逗号匹配的正则表达式:

:sort/^[^,]*,/

比较在:sort每行指定模式匹配之后开始的文本,它为我们提供了所需的排序行为。要按数字而不是按字典顺序比较值,请使用以下n 标志:

:sort n/^[^,]*,/

2.第二步涉及遍历已排序的行,并在第二列中具有相同值的每个连续行块中删除除一个之外的所有行。在命令上构建我们的实现很方便:global,该命令在匹配特定模式的每一行上执行给定的 Ex 命令。出于我们的目的,如果该行在第二列中包含与以下行相同的值,则可以删除该行。这种形式化——伴随着逗号不能出现在列值中的初始假设——为我们提供了以下模式:

^[^,]*,\([^,]*\),.*\n[^,]*,\1,.*

如果我们在:delete满足此模式的每一行上运行命令,从上到下按排序顺序排列,我们将只有一行用于第二列中的每个不同值:

:g/^[^,]*,\([^,]*\),.*\n[^,]*,\1,.*/d_

3.最后,这两个步骤可以组合在一个 Ex 命令中:

:sort/^[^,]*,/|g/^[^,]*,\([^,]*\),.*\n[^,]*,\1,.*/d_
于 2012-04-20T02:48:28.310 回答
1
:sort /\([^,]*,\)\{1}/
:g/\%(\%([^,]*,\)\{1}\1.*\n\)\@<=\%([^,]*,\)\{1}\([^,]*\)/d

首先按索引为 1 的列排序。第二个匹配列索引 1 与下一行列索引 1 匹配的任何行并将其删除。

列索引是 1 中的{1}。它重复了3次。

于 2012-04-20T10:54:09.523 回答
-1

使用第二列

(visual + !sort)

使用第三列

sort -k 3 

或者

:sort /.*\%3v/

或者

select the lines you wish to sort using the Capital V command. Then enter
!sort -k 3n

或跳过每行中的前两个单词并按以下内容排序:

:%sort /^\S\+\s\+\S\+\s\+/ 

或者

按最后一列排序

:%sort /\<\S\+\>$/ r

或使用其他程序,如 MS OFFICE 或 OPENOFFICE

于 2013-03-27T13:14:31.760 回答