检测Windows中文件名的大小写不匹配(最好使用python)?

时间:2009-08-31 08:13:45

标签: python windows case-sensitive

我有一些我们在Windows环境中创建但在Linux上部署的xml配置文件。这些配置文件使用文件路径相互引用。我们之前遇到过区分大小写和尾随空格的问题,我想编写一个检查这些问题的脚本。如果有帮助,我们有Cygwin。

示例:

假设我有一个文件foo / bar / baz.xml的引用,我会这样做

<someTag fileref="foo/bar/baz.xml" />

现在如果我们错误地这样做了:

<someTag fileref="fOo/baR/baz.Xml  " />

它仍可在Windows上运行,但在Linux上会失败。

我想要做的是检测这些文件中的文件引用与区分大小写的实际文件不匹配的情况。

2 个答案:

答案 0 :(得分:3)

目录上的

os.listdir,在所有保留案例的文件系统(包括Windows上的文件系统)中,返回您列出的目录中文件名的实际大小写。

所以你需要在路径的每个级别进行检查:

def onelevelok(parent, thislevel):
  for fn in os.listdir(parent):
    if fn.lower() == thislevel.lower():
      return fn == thislevel
  raise ValueError('No %r in dir %r!' % (
      thislevel, parent))

我假设完全没有任何名称变体的名称是一种不同的错误,并使用例外;并且,对于整个路径(假设没有驱动器号或UNC无论如何都不会转换为Windows):

def allpathok(path):
  levels = os.path.split(path)
  if os.path.isabs(path):
    top = ['/']
  else:
    top = ['.']
  return all(onelevelok(p, t)
             for p, t in zip(top+levels, levels))

如果foo/bar不是指foo在当前目录中,而是在其他地方,则可能需要对此进行调整;或者,当然,如果事实上需要UNC或驱动器号(但正如我提到的那样,将它们翻译成Linux并不是无关紧要的事情; - )。

实施说明:我正在利用这样一个事实,即zip只是删除“额外条目”超出其最短的序列的长度;所以我不需要在第一个参数中明确地从levels切掉“叶子”(最后一个条目),zip为我做。 all会尽可能地短路,一旦检测到错误值就会返回False,因此它就像显式循环一样好但更快更简洁。

答案 1 :(得分:0)

很难判断出您的问题究竟是什么,但如果您在保存文件名之前应用os.path.normcasestr.stript,则应解决所有问题。

正如我在评论中所说的,目前尚不清楚你是如何以这样的错误结束的。但是,只要您有一些合理的约定(例如,所有文件名都是小写的),检查现有文件将是微不足道的:

try:
    open(fname)
except IOError:
    open(fname.lower())