【问题标题】:Custom sort to sort particular field in huge data set自定义排序以对庞大数据集中的特定字段进行排序
【发布时间】:2021-06-26 08:56:42
【问题描述】:

我有一个场景.. 我需要进行自定义排序 在第 4 列中......这些是可能的值。
TUN
PB
TP

我可以对整个数据集的第一个和第二个字段使用排序 文件大小> 500MB,因此还应考虑性能。 但是对于第 4 个字段.. 我必须创建一个自定义排序,以便输出将按此顺序用于第 4 个字段。
TUN
PB
TP

输入数据:

0022|||PB||||||||||||||||
0022|||TN|0|||||||||||||||||||||

预期输出是

0022||TN|0|||||||||||||||||||||
0022|||PB||||L|||||||||||||||||||||||

有什么建议吗?

【问题讨论】:

  • 使用awk添加另一列,1代表TUNES,2代表PLAYBACK,3代表TRICKPLAY,然后对该列进行排序,之后使用cut将其删除。
  • @Shawn:添加新列有什么帮助?我已经有 23 列数据.. 仅在第 4 个字段中,将出现该字段之一。由于我没有按所需的顺序得到它,而且按字母顺序排序没有帮助,因此必须进行自定义排序
  • edit您的问题并显示一些示例输入、您用于排序的命令以及实际和预期的输出。
  • 然后您可以对该列进行数字排序以获得您想要的顺序。
  • @Shawn:数字排序没有给我们所需的顺序

标签: linux bash shell unix csh


【解决方案1】:

您正在寻找的是一个名为 decorate-sort-undecorate 的成语。这个想法是根据您要排序的数据添加一个具有可排序值的列,对其进行排序,然后删除额外的列以按正确的顺序获取原始数据。

例子:

$ cat sample.txt
a|b|c|PLAYBACK|x
d|e|f|TUNES|y
g|h|i|TRICKPLAY|z
$ awk 'BEGIN { FS=OFS="|"; order["TUNES"] = 1
               order["PLAYBACK"] = 2; order["TRICKPLAY"] = 3 }
       { print order[$4], $0 }
      '  sample.txt | sort -t'|' -k1,1n | cut -d'|' -f 2-
d|e|f|TUNES|y
a|b|c|PLAYBACK|x
g|h|i|TRICKPLAY|z

当然,您必须调整排序键以获得所需的最终排序(您提到对其他列进行排序,但没有说明它们应该用作排序键的顺序)。

【讨论】:

  • 旁注:sortcut 对列分隔符使用不同的选项,这让我很烦恼。一致性,你的名字不是Unix。
  • 脚本可以通过在第一列之前插入额外的列来简化并独立于实际的列数,例如awk 'BEGIN {...} { print order[$4],$0 }' sample.txt | sort | cut -d'|' -f 2-
  • @Bodo 好建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
  • 1970-01-01
相关资源
最近更新 更多