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

Jon*_*nah 8 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
Run Code Online (Sandbox Code Playgroud)

sort命令应该产生:

a,1,b
i,2,l
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢!

ib.*_*ib. 11

由于在一次运行:sort命令中无法在问题下实现转换,因此我们将其视为一个两步过程.

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

:sort/^[^,]*,/
Run Code Online (Sandbox Code Playgroud)

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

:sort n/^[^,]*,/
Run Code Online (Sandbox Code Playgroud)

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

^[^,]*,\([^,]*\),.*\n[^,]*,\1,.*
Run Code Online (Sandbox Code Playgroud)

因此,如果我们:delete在满足此模式的每一行上运行命令,从上到下,我们将只为第二列中的每个不同值提供一行.

:g/^[^,]*,\([^,]*\),.*\n[^,]*,\1,.*/d_
Run Code Online (Sandbox Code Playgroud)

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

:sort/^[^,]*,/|g/^[^,]*,\([^,]*\),.*\n[^,]*,\1,.*/d_
Run Code Online (Sandbox Code Playgroud)