【问题标题】:Sort CSV file by column priority using the "sort" command使用“排序”命令按列优先级对 CSV 文件进行排序
【发布时间】:2012-02-27 19:36:15
【问题描述】:

我有一个 csv 文件,我想按列优先级对其进行排序,例如“排序依据”。例如:

3;1;2
1;3;2
1;2;3
2;3;1
2;1;3
3;2;1

如果这种情况是“选择”的结果,则“排序依据”如下: order by column2, column1, column3 - 结果将是:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1

我想知道如何在 Unix 上使用“排序”命令获得同样的结果。

【问题讨论】:

  • 顺便说一下,这是一个ssv文件(分号分隔值):P
  • 可悲的是,sort 在现实世界中是一个不可靠的基础,而报价恰好是

标签: unix sorting csv sql-order-by


【解决方案1】:
sort --field-separator=';' --key=2,1,3

【讨论】:

  • 如果值是数字,那么您可能需要考虑使用“根据字符串数值比较”的-n 选项或“根据一般数值比较”的-g 选项”。数值的字符串比较将得到像1,10,2,20 这样排序的数字。至少这些是我在 CentOS 上的排序版本可用的选项。您应该使用手册页验证您的 sort 版本中的正确选项。
  • 我收到sort: stray character in field spec: invalid field specification ‘2,1,3’
  • 然而,sort --field-separator=',' -r -k3 -k1 -k2 source.csv > target.csv 为我工作。
  • @MartinThoma 已经很久了,但我遇到了你的问题,我发现sort --field-separator=';' --key={2,1,3}。这从 2016 年 4 月起在 GNU coreutils 8.4 工作
  • @mrbolichi 符号 --key={2,1,3} 使用 bash 的大括号扩展
【解决方案2】:

假设您的unsorted.csv 文件中有另一行3;10;3。那么我猜你希望得到一个按数字排序的结果:

2;1;3
3;1;2
1;2;3
3;2;1
1;3;2
2;3;1
3;10;3

而不是按字母顺序排序的:

2;1;3
3;1;2
3;10;3
1;2;3
3;2;1
1;3;2
2;3;1

为此,您必须使用-n

sort --field-separator=';' -n -k 2,2 -k 1,1 -k 3,3 unsorted.csv

值得一提的是2,2必须使用。如果只使用2,则sort 将字符串从字段2 的开头带到结尾。 2,2 确保仅使用字段 2

【讨论】:

  • 关于 -k 2 和 -k 2,2 之间区别的指针很重要!我在第一次阅读手册页时忽略了这一点。谢谢。
  • 我在源文件中按顺序添加了几行,3;10;33:10:53:10;23;10;3,当使用 just @ 987654336@ 它似乎在第 2 列和第 3 列排序。手册页显示 "The -k option may be specified multiple times, in which case subsequent keys are compared when earlier keys compare equal."。在我的情况下,较早的键 (value=10) 确实比较相等,但是,我没有多次指定 -k。我不确定这是否是可靠的行为,或者与我的系统(mac)有关。不过最终都没有关系,只要主排序是正确的。
  • 哦,我看到还有 -s 稳定排序忽略相等的键,这显然更快。
【解决方案3】:

上面查理的回答在 Cygwin 上对我不起作用(排序版本 2.0,GNU textutils),以下是:

sort -t"," -k2 -k1 -k1

【讨论】:

  • Cygwin 有一个旧版本的排序。一如既往,手册页是您的朋友。
  • 我同意@CharlieMartin,您应该查看系统上的手册页。在 CentOS 上我使用了sort --field-separator=';' -k2 -k1 -k3 test.csv
【解决方案4】:

..如果有人遵循“排序”解决方案,但现在想要获得的不仅仅是每行单个唯一条目(即唯一条目的前 X 个),一旦您使用“排序”对文件进行了排序,你可以使用我在这里创建的一个小应用程序:

https://github.com/danieliversen/MiscStuff/blob/master/scripts/findTopUniques.java

【讨论】:

  • 对你有好处!但在您的情况下,您可以只使用 cat unsorted-file | sort | uniq | head -X - 当 X 是您希望输出的第一行数时。
  • @SlavikMe 非常感谢您的评论!但是,您的建议给出了不同的结果。您的建议在完全排序的文件中获得前 X 行,而我们希望获得每个“键”的前 X 行(即,如果您有一个带有名称的 CSV,那么如果您排序通过第 2 列“姓氏”,那么您的命令可能只会得到 3 行“艾伦”作为姓氏,而我们的命令会得到“艾伦”、“英国”、“查尔斯”等)。不过谢谢!
  • 你错了。我建议在评论之前尝试一下我写的命令。请注意,在sorthead 之间有一个以管道顺序排列的命令uniq,它在提取顶部行之前为所有已排序的行提供唯一性。
  • 这个解决方案没有回答这个问题,因为它特别要求使用命令sort
猜你喜欢
  • 1970-01-01
  • 2022-11-11
  • 2019-10-04
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-13
相关资源
最近更新 更多