繁体   English   中英

如何在 Vim 中对 CSV 表运行 ':sort u' 命令,但仅使用特定列中的值作为排序键?

[英]How to run the ‘:sort u’ command in Vim on a CSV table, but only use the values in a particular column as sorting keys?

我正在寻找一个更具体的: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 命令会产生上面的输出?

谢谢!

由于不可能在一次运行: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_
:sort /\([^,]*,\)\{1}/
:g/\%(\%([^,]*,\)\{1}\1.*\n\)\@<=\%([^,]*,\)\{1}\([^,]*\)/d

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

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

使用第二列

(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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM