如何在Unix中按字母数字排序?比看起来更复杂

时间:2011-12-06 04:34:12

标签: python bash shell unix sorting

我正在尝试使用unix sort命令以“直观”/自然的方式按字母数字字母和数字排序,但无法正确排序。我有这个文件:

$ cat ~/headers 
@42EBKAAXX090828:6:100:1699:328/2
@42EBKAAXX090828:6:10:1077:1883/2
@42EBKAAXX090828:6:102:785:808/2

我想按字母顺序排序,直觉@42EBKAAXX090828:6:10:...是第一个(因为10小于100102),其次是{{1}第三个是@42EBKAAXX090828:6:100...

我知道建议对行内的特定位置进行排序,但此处@42EBKAAXX090828:6:102:204:1871/2的位置可能会有所不同,因此这不是一个通用且可行的解决方案。

我试过了:

:

使用sort --stable -k1,1 ~/headers > foo -n参数的各种组合,但它没有给出正确的排序。

如何从使用-u的bash或Python中有效地完成此操作?我想将它应用于大小为4-5 GB的文件,因此包含数百万行。

谢谢!

3 个答案:

答案 0 :(得分:11)

-V选项似乎可以执行您想要的操作 - 自然排序。明显用于版本号(因此选择了字母)

sort -V ~/headers

输出

@42EBKAAXX090828:6:10:1077:1883/2
@42EBKAAXX090828:6:100:1699:328/2
@42EBKAAXX090828:6:102:785:808/2

答案 1 :(得分:4)

按字母顺序对其进行排序,就像在您的示例中一样。 10:100之后的102之后的原因是10: 之后,因为冒号:位于9之后ASCII chart中的sort -t':' -k3 ~/headers > foo 字符。

如果您想对冒号分隔的第三个字段进行排序,请尝试以下方法:

{{1}}

答案 2 :(得分:0)

这通常称为自然排序。这是一种适用于您的示例数据集的方法。

import re

def natural_sorted(iterable, reverse=False):
    """Return a list sorted the way that humans expect."""
    def convert(text):
        return int(text) if text.isdigit() else text
    def natural(item):
        return map(convert, re.split('([0-9]+)', item))
    return sorted(iterable, key=natural, reverse=reverse)

我发现了这个here并且有所改进。