:排序你 - 但只在csv的一列?

时间:2012-04-19 22:16:22

标签: vim

我正在寻找更具体的:sort u命令版本,它将从文件中删除所有重复的行。我正在使用csv,我想删除第二列条目重复的所有行。一个例子应该有助于澄清:

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

sort命令应该产生:

a,1,b
i,2,l

注意:保留的特定行并不重要,只要在排序后第二列条目都是唯一的

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

谢谢!

3 个答案:

答案 0 :(得分:10)

由于无法在问题中实现转型 在:sort命令的一次运行中,让我们将其视为一个两步过程。

第一步是按第二个逗号分隔的值对行进行排序 柱。为此,我们可以使用:sort命令传递常规 与第一列和以下分隔逗号匹配的表达式。 当:sort比较在指定匹配之后开始的文本 每行上的模式,它为我们提供了所需的排序顺序。

:sort/^[^,]*,/

要以数字方式比较值,而不是按字典顺序,请使用n标记:

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

第二步涉及遍历已排序的行并删除所有行 他们只是第二列中具有相同价值的人之一。它是 方便在:global命令上构建我们的实现 在匹配特定模式的行上执行Ex命令。根据定义, 如果一行在第二列中包含相同的值,则可以删除该行 下一行。这种形式化(伴随着最初的假设 逗号不能出现在列值中)给出了以下模式:

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

因此,如果我们在满足此模式的每一行上运行:delete命令, 从上到下,我们将只有一行代表每个不同的值 第二栏。

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

这两个步骤可以组合在一个Ex命令中,

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

答案 1 :(得分:1)

:sort /\([^,]*,\)\{1}/
:g/\%(\%([^,]*,\)\{1}\1.*\n\)\@<=\%([^,]*,\)\{1}\([^,]*\)/d

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

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

答案 2 :(得分:0)

使用第二列

(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

OR 使用另一个程序,如MS OFFICE或OPENOFFICE