【问题标题】:sort numerically then alphnumerically on the same column按数字排序,然后在同一列上按字母数字排序
【发布时间】:2018-06-01 09:20:02
【问题描述】:

我有非常大的数据要排序

  • 第 1 列:先是数字,然后是字母
  • 然后在第 2 列:数字。

所以,我的最终输出是这样的:

1    11  
1    13
1    15
2    3
2    5
chr2   6
chr2   15
chr15   3
chr15   9

我在 unix 上使用sort。但是,无论我尝试什么类型,我都会将 chr2 放在顶部或底部。以下是我尝试过的一些类型:它无法给我想要的输出:

sort -V -k1,1n -k2n final_merged.txt > merged-sort.txt
sort -k1,1n -k2n final_merged.txt > merged-sort.txt 
sort -k1,1h -k2n final_merged.txt > merged-sort.txt
sort -k1,1 -k2n final_merged.txt > merged-sort.txt

后期编辑:任何解决此问题的方法,而不会在使用时使内存过载

  • 排序或其他 unix 实用程序
  • 蟒蛇

谢谢,

【问题讨论】:

  • 第 1 列中的前缀是否始终为 chr(或至少相同数量的字符)?
  • 可能会有所不同。这种排序整天给我带来麻烦。我阅读了几个排序教程,但无法解决这个问题。
  • @chepner : 任何方式都可以解决这个问题。
  • 您想要数字排序,但 'chr2' 不是数字。您需要一个预处理步骤,将第一列拆分为 2 列,其中一个是“chr”(或空白:在只有数字的情况下),然后是数字。可能 sed 或 awk 可以做到这一点

标签: python shell sorting ubuntu unix


【解决方案1】:

试试:

sort -k1,2 -V final_merged.txt

使用您的示例数据运行它会得到:

1    11
1    13
1    15
2    3
2    5
chr2   6
chr2   15
chr15   3
chr15   9

【讨论】:

  • 完美。我应该移动那个V
【解决方案2】:

您需要数字排序,但 'chr2' 不是数字。您需要一个预处理步骤,将第一列分成两列,即文本部分和数字部分。

gawk 'match($1, /([^0-9])*([0-9]*)/, a) {print a[1], a[2], $2}' /tmp/abc | sort -t ' ' -k1,1 -k2,2n -k3,3n

使用 gawk 拆分正则表达式,非数字然后是数字,然后是第 2 列(现在用单个空格分隔)。

按单个空格分隔的列排序。

gawk '{print $1 $2, $3}' 重新组合列。

您可能需要修改这些以保留所需的任何空白。

【讨论】:

    【解决方案3】:

    Python 解决方案:

    初始化Natural Sort

    import re
    
    _nsre = re.compile('([0-9]+)')
    def natural_sort_key(s):
        return [int(text) if text.isdigit() else text.lower()
                for text in re.split(_nsre, s)]
    

    然后根据需要进行排序:

    sorted_data = sorted(data, key=lambda item: (natural_sort_key(str(item[0])), item[1]))
    

    主要对item[0]natural sort 进行排序,然后在item[1] 上进行数字排序。

    【讨论】:

    • OP 声明集合不适合内存,这个 python 甚至要求数据在内存中两次
    猜你喜欢
    • 1970-01-01
    • 2020-09-03
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    相关资源
    最近更新 更多