【问题标题】:How to sort glob.glob containing numbers? [duplicate]如何对包含数字的 glob.glob 进行排序? [复制]
【发布时间】:2021-07-15 13:52:54
【问题描述】:

在做

glob.glob('/var/log/apache2/other_vhosts_access.log*')

给出一个未排序的列表,例如['....76.gz', '....16.gz', '....46.gz', ...]。还有,

sorted(glob.glob('/var/log/apache2/other_vhosts_access.log*')) 

给予

other_vhosts_access.log
other_vhosts_access.log.1
other_vhosts_access.log.10.gz
other_vhosts_access.log.11.gz
other_vhosts_access.log.12.gz
...
other_vhosts_access.log.19.gz
other_vhosts_access.log.2.gz

如何进行更好的排序? .log, .log.1, .log.2.gz, ..., .log.9.gz, .log.10.gz, ...

【问题讨论】:

  • 您可以创建自己的排序键函数并将其传递给sorted,排序键可以提取数字,并将其作为int返回。
  • @RufusVS 是的,sorted(..., key=...),但我更多的是寻找一个不针对每种情况进行编码的通用解决方案。

标签: python sorting glob natural-sort


【解决方案1】:

为了扩展我的评论,也许这样的事情会做。这会提取在小数点之间或文件末尾找到的第一个数字序列,并将该值用作主排序键,并使用完整的文件名作为辅助键。

file_list = """
other_vhosts_access.log
other_vhosts_access.log.1
other_vhosts_access.log.10.gz
other_vhosts_access.log.11.gz
other_vhosts_access.log.12.gz
other_vhosts_access.log.19.gz
other_vhosts_access.log.2.gz
""".strip().split()

import re

re_num = r"\.(\d+)(\.|$)"

def sort_key(file_name):
    match=re.search(re_num,file_name)
    if match is None:
        return(0,file_name)
    else:
        return(int(match.group(1)),file_name)
    
print(*sorted(file_list,key=sort_key),sep='\n')

【讨论】:

  • 没有硬编码这个正则表达式搜索的通用方法吗?
  • 我不确定您所说的“一般”方式是什么意思。每种方式都必须包含一种使用某种规则来解析文件名以建立排序顺序的方法。
  • 难道没有通用的“自然排序”方式来做到这一点@RufusVS?以下是它与/bin/ls 的工作方式:unix.stackexchange.com/questions/33909/…
  • 封闭注释和其他答案中指定的链接中有更好(更通用)的解决方案。哦!你发布了那个答案!
【解决方案2】:

基于Is there a built in function for string natural sort?,这里有一个单行解决方案:

natsort = lambda s: [int(t) if t.isdigit() else t.lower() for t in re.split('(\d+)', s)]

sorted(glob.glob('/var/log/apache2/other_vhosts_access.log*'), key=natsort)

【讨论】:

  • 这本质上是该答案的副本。作为重复 IMO 关闭的好案例
  • 感谢您链接重复的@PranavHosangadi。注意:我明确引用了原始问题,我不是为了代表,而是为了完整性,以便任何人都可以快速找到解决方案而无需阅读那里的许多答案。不确定在这里投反对票是否真的有用;)
  • 我喜欢单线!我现在必须了解re.split
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-19
  • 2020-04-14
  • 2011-06-02
  • 1970-01-01
相关资源
最近更新 更多