4

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

例子:

假设我引用了文件 foo/bar/baz.xml,我会这样做

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

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

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

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

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

4

2 回答 2

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))

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

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一旦检测到错误值就会返回,因此它与显式循环一样好,但更快更简洁。

于 2009-08-31T14:45:10.710 回答
0

很难判断你的问题到底是什么,但如果你在保存文件名之前申请os.path.normcasestr.stript它应该可以解决你所有的问题。

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

try:
    open(fname)
except IOError:
    open(fname.lower())
于 2009-08-31T10:12:25.000 回答