Обнаружение несоответствия регистра имени файла в Windows (желательно с использованием Python)? - PullRequest
4 голосов
/ 31 августа 2009

У меня есть несколько файлов конфигурации xml, которые мы создаем в среде Windows, но развернуты в Linux. Эти файлы конфигурации ссылаются друг на друга с помощью filepaths. У нас раньше были проблемы с чувствительностью к регистру и конечными пробелами, и я хотел бы написать скрипт, который проверяет эти проблемы. У нас есть Cygwin, если это поможет.

Пример:

Допустим, у меня есть ссылка на файл foo / bar / baz.xml, я бы сделал это

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

Теперь, если мы по ошибке сделаем это:

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

Он все еще будет работать в Windows, но не будет работать в Linux.

Что я хочу сделать, это обнаружить эти случаи, когда ссылка на файл в этих файлах не соответствует реальному файлу в отношении чувствительности к регистру.

Ответы [ 2 ]

3 голосов
/ 31 августа 2009

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, как только он обнаружит ложное значение, так что это так же хорошо, как явный цикл, но быстрее и более кратким.

0 голосов
/ 31 августа 2009

Трудно судить, в чем конкретно заключается ваша проблема, но если вы примените os.path.normcase вместе с str.stript перед сохранением имени файла, это должно решить все ваши проблемы.

как я сказал в комментарии, неясно, как вы в конечном итоге с такой ошибкой. Тем не менее, было бы тривиально проверить наличие файла, если у вас есть разумное соглашение (например, все имена файлов в нижнем регистре):

try:
    open(fname)
except IOError:
    open(fname.lower())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...