我有一些我们在Windows环境中创建但在Linux上部署的xml配置文件。这些配置文件使用文件路径相互引用。我们之前遇到过区分大小写和尾随空格的问题,我想编写一个检查这些问题的脚本。如果有帮助,我们有Cygwin。
示例:
假设我有一个文件foo / bar / baz.xml的引用,我会这样做
<someTag fileref="foo/bar/baz.xml" />
现在如果我们错误地这样做了:
<someTag fileref="fOo/baR/baz.Xml " />
它仍可在Windows上运行,但在Linux上会失败。
我想要做的是检测这些文件中的文件引用与区分大小写的实际文件不匹配的情况。
答案 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.normcase
和str.stript
,则应解决所有问题。
try:
open(fname)
except IOError:
open(fname.lower())