2009-08-31 4 views
4

J'ai des fichiers de configuration xml que nous créons dans un environnement Windows mais qui sont déployés sous Linux. Ces fichiers de configuration se réfèrent les uns aux autres avec des chemins de fichiers. Nous avons déjà eu des problèmes avec la sensibilité à la casse et les espaces de fin, et j'aimerais écrire un script qui vérifie ces problèmes. Nous avons Cygwin si cela aide.Détection d'incompatibilité de casse sur le nom de fichier dans Windows (de préférence en utilisant python)?

Exemple:

Disons que j'ai une référence au fichier foo/bar/baz.xml, je ferais ce

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

Maintenant, si nous par erreur le faire:

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

Il fonctionnera toujours sur Windows, mais il échouera sur Linux.

Ce que je veux faire est de détecter ces cas où la référence du fichier dans ces fichiers ne correspond pas au fichier réel en ce qui concerne la sensibilité à la casse.

+0

Il n'est pas clair comment vous vous retrouvez avec une erreur comme celle-ci. êtes-vous en train de coder ces valeurs? – SilentGhost

Répondre

3

os.listdir sur un répertoire, dans tous les systèmes de fichiers de cas préservant (y compris ceux sous Windows), renvoie le cas réel pour les noms de fichiers dans le répertoire que vous répertoriez.

Vous devez effectuer cette vérification à chaque niveau du chemin:

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

où je suppose que l'absence totale de toute variation de cas d'un nom est un autre type d'erreur, et l'utilisation de une exception pour cela; et, pour le chemin entier (en supposant aucune lettre de lecteur ou UNC qui ne se traduira pas à Windows de toute façon):

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

Vous devrez peut-être adapter ce cas, par exemple, foo/bar ne doit pas être interprété comme signifiant que foo est dans le répertoire courant, mais ailleurs; ou, bien sûr, si UNC ou des lettres de lecteur sont en fait nécessaires (mais comme je l'ai mentionné, les traduire en Linux n'est pas trivial de toute façon ;-).

Notes d'implémentation: Je profite du fait que zip laisse simplement tomber les "entrées supplémentaires" au-delà de la plus courte des séquences qu'il zippe; donc je n'ai pas besoin de découper explicitement la "feuille" (dernière entrée) de levels dans le premier argument, zip le fait pour moi. all court-circuitera où il le peut, renvoyant False dès qu'il détecte une valeur fausse, il est donc aussi bon qu'une boucle explicite mais plus rapide et plus concis.

+0

Je me doutais que je devais faire quelque chose comme ça. Je vais devoir l'adapter un peu car foo/bar/baz.xml n'est pas relatif au répertoire courant. C'est relatif à un (petit) nombre de chemins de niveau supérieur possibles. –

0

il est difficile de juger quel est exactement votre problème, mais si vous appliquez os.path.normcase avec str.stript avant d'enregistrer votre nom de fichier, il devrait résoudre tous vos problèmes. Comme je l'ai dit dans le commentaire, il n'est pas clair comment vous vous retrouvez avec une telle erreur. Cependant, il serait trivial de vérifier le fichier existant, aussi longtemps que vous avez une convention raisonnable (tous les noms de fichiers sont minuscules, par exemple):

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

J'ai ajouté un exemple pour clarifier. –

+0

La chose qui à la fin ouvre les fichiers est la source fermée, et n'est pas sous mon contrôle. C'est pourquoi j'ai besoin de valider les fichiers. Et oui, les références de fichiers sont ajoutées à la main dans un outil sur lequel je n'ai aucun contrôle. –

+0

La question est de savoir si vous avez une convention pour vos noms de fichiers. Autrement dit, comment savez-vous que le nom correct du fichier est '* .xml' et non pas * .Xml'? Vous réalisez que vous ne pouvez pas simplement vérifier chaque combinaison possible de cas pour savoir lequel existe? – SilentGhost

Questions connexes