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

发布于 2024-12-19 19:53:08 字数 784 浏览 0 评论 0原文

我试图使用 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),第二个是 @42EBKAAXX090828:6:100... 第三个是@42EBKAAXX090828:6:102:204:1871/2

我知道建议在行内的特定位置进行排序,但是这里 : 的位置可能会有所不同,因此这不是一个通用且可行的解决方案。

我尝试过:

sort --stable -k1,1 ~/headers > foo

使用 -n-u 参数的各种组合,但它没有给出正确的顺序。

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

谢谢!

I'm trying to sort a string of letters and numbers alphanumerically in an "intuitive"/natural way using the unix sort command, but cannot get it to sort properly. I have this file:

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

I'd like to sort it alphanumerically, where intuitively @42EBKAAXX090828:6:10:... is first (since 10 is smaller than 100 and 102), second is @42EBKAAXX090828:6:100... and third is @42EBKAAXX090828:6:102:204:1871/2.

I know that suggest sorting on a particular position within the line, but the position of the : here could vary and so this would not be a general and workable solution here.

I tried:

sort --stable -k1,1 ~/headers > foo

with various combinations of -n and -u parameters but it does not give the correct ordering.

How can this be done efficiently, either from bash using sort or from Python? I'd like to apply this to files that are round 4-5 GB in size, so containing millions of lines.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝礼 2024-12-26 19:53:08

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

sort -V ~/headers

输出

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

the -V option appears to do what you want - natural sorting. Intended for version numbers apparently (hence the letter chosen)

sort -V ~/headers

outputs

@42EBKAAXX090828:6:10:1077:1883/2
@42EBKAAXX090828:6:100:1699:328/2
@42EBKAAXX090828:6:102:785:808/2
梦情居士 2024-12-26 19:53:08

按字母顺序对其进行排序,就像您的示例中一样。 10: 出现在 100102 之后的原因是 10: 在它们之后,因为冒号 : 位于 中的 9 字符之后ASCII 图表

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

sort -t':' -k3 ~/headers > foo

It is sorting it alphabetically as it is in your example. The reason 10: is coming after 100 and 102 is that 10: is after them, since the colon : is after the 9 character in the ASCII chart.

If you're wanting to sort on the third field delimited by a colon, try this:

sort -t':' -k3 ~/headers > foo
甩你一脸翔 2024-12-26 19:53:08

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

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)

我在这里找到了这个改善了一点。

This is usually called Natural Sorting. Here's one way that works for your example data set.

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)

I found this here and improved a bit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文