忽略Linux上的glob()中的大小写

and*_*s-h 35 python linux

我正在编写一个脚本,该脚本必须处理由Windows和Linux用户手动修改的目录.Windows用户往往不关心分配文件名的情况.

有没有办法在Python的Linux端处理这个问题,即我可以得到一个不区分大小写,类似于glob的行为吗?

Geo*_*ing 46

您可以用[cC],via替换每个字母c

import glob
def insensitive_glob(pattern):
    def either(c):
        return '[%s%s]' % (c.lower(), c.upper()) if c.isalpha() else c
    return glob.glob(''.join(map(either, pattern)))
Run Code Online (Sandbox Code Playgroud)

  • shao.lo:是的,确实有更长的优势. (6认同)
  • 为了更加pythonic ...或者至少让pylint高兴`return glob.glob(''.join(在模式中为char设置(char)) (3认同)
  • 这个解决方案有严重的缺点,所以要小心。首先,```glob()``` 在 Windows 驱动器盘符上使用这种模式将失败。然后,同样适用于使用“magic”文件夹,例如“sysnative”文件夹。 (2认同)
  • @craymichael 看来,通过使用 `f'[{c.lower()}{c.upper()}]'` 而不是 `%` 运算符来创建,您可以在 Python 3.6+ 中再减少 10% 的运行时间字符串。我还发现,通过适当的语法突出显示,它非常清晰! (2认同)

Fre*_*Foo 24

使用不区分大小写的正则表达式而不是glob模式.fnmatch.translate从glob模式生成一个正则表达式,所以

re.compile(fnmatch.translate(pattern), re.IGNORECASE)
Run Code Online (Sandbox Code Playgroud)

给出一个不区分大小写的glob模式版本作为编译的RE.

请记住,如果文件系统是通过在类Unix文件系统在Linux中托管,用户将能够创建文件foo,FooFOO在同一目录下.

  • 经过 2 小时摆弄“os.walk”之后,我不知所措。你能多给点建议吗?我很难弄清楚“dirs”周围的循环,匹配“re”并适当地中断。可能不是我的日子:( (2认同)
  • 我会接受这个答案,因为它给出了有效的答复.但是,出于速度原因,我决定使用更加量身定制的`os.walk`和`os.listdir`组合. (2认同)

Raf*_*ffi 6

非递归

要使用"globexpression"检索目录"path"的文件(和仅文件):

list_path = [i for i in os.listdir(path) if os.path.isfile(os.path.join(path, i))]
result = [os.path.join(path, j) for j in list_path if re.match(fnmatch.translate(globexpression), j, re.IGNORECASE)]
Run Code Online (Sandbox Code Playgroud)

递归

散步:

result = []
for root, dirs, files in os.walk(path, topdown=True):
  result += [os.path.join(root, j) for j in files \
             if re.match(fnmatch.translate(globexpression), j, re.IGNORECASE)]
Run Code Online (Sandbox Code Playgroud)

最好也编译正则表达式,而不是

re.match(fnmatch.translate(globexpression)
Run Code Online (Sandbox Code Playgroud)

做(在循环之前):

reg_expr = re.compile(fnmatch.translate(globexpression), re.IGNORECASE)
Run Code Online (Sandbox Code Playgroud)

然后在循环中替换:

  result += [os.path.join(root, j) for j in files if re.match(reg_expr, j)]
Run Code Online (Sandbox Code Playgroud)