2011-12-11 14 views
8

मुझे इसे नाम देने वाली फ़ाइल लोड करने की आवश्यकता है, लेकिन मुझे जो नाम मिलता है वह मामला असंवेदनशील है। "एटीटीटी" वास्तव में "a.txt" हो सकता है। यह तेज़ तरीका कैसे करें (सभी संभावित नाम उत्पन्न न करें और प्रत्येक को आजमाएं)?पायथन केस असंवेदनशील फ़ाइल नाम?

+0

क्या ओएस पर आप कर रहे हैं? – vdbuilder

+0

कोई फर्क नहीं पड़ता, मुझे जो नाम मिलता है (जो मामला असंवेदनशील है) को स्क्रिप्ट फ़ाइल से पार्स किया गया है। –

+0

ऑपरेटिंग सिस्टम (और वास्तव में फाइल सिस्टम) निश्चित रूप से यहां प्रासंगिक हैं। – Johnsyweb

उत्तर

6

आप निर्देशिका में फ़ाइल को सूचीबद्ध कर सकते हैं (os.listdir), और देखें कि आपके फ़ाइल नाम के लिए मिलान हैं या नहीं। मिलान दोनों फाइलनामों और तुलना के निचले-आवरण से किया जा सकता है।

+0

हाँ, लेकिन क्या यह कुशल है? फ़ोल्डर को ध्यान में रखते हुए हजारों फाइलें हो सकती हैं? –

+4

@ user975135: जब तक आप इस दृष्टिकोण की कोशिश नहीं करते हैं तब तक मैं अक्षमता की चिंता नहीं करता और यह आपकी आवश्यकताओं के लिए बहुत धीमी है। – dreamlax

+0

वैसे मैंने पाइथन के साथ एक बार में हजारों तारों को संसाधित किया है, इसलिए मुझे लगता है कि अगर कोई दूसरा तरीका है तो मुझे इसे अनदेखा नहीं करना चाहिए। –

1

एक निर्देशिका सूची बनाना; और ऊपरी-केस फ़ाइल नामों के मैपिंग को उनके वास्तविक-केस फ़ाइल नामों में एक शब्दकोश बनाएं। फिर, अपना इनपुट ऊपरी-केस बनाएं, और शब्दकोश में इसे देखें।

5

आप निर्देशिका सूची के बिना ऐसा नहीं कर सकते हैं और जिस आइटम को आप खोज रहे हैं और प्रत्येक निर्देशिका में तुलना के लिए एक सामान्य मामले में ले जा सकते हैं। फाइल सिस्टम केस संवेदनशील है और यह सब कुछ है।

यहां एक फ़ंक्शन (ठीक है, दो) है जिसे मैंने पूरी तरह से करने के लिए लिखा है, एक फ़ाइल नाम से असंवेदनशील तरीके से मेल खाता है, http://portableapps.hg.sourceforge.net/hgweb/portableapps/development-toolkit/file/775197d56e86/utils.py#l78

def path_insensitive(path): 
    """ 
    Get a case-insensitive path for use on a case sensitive system. 

    >>> path_insensitive('/Home') 
    '/home' 
    >>> path_insensitive('/Home/chris') 
    '/home/chris' 
    >>> path_insensitive('/HoME/CHris/') 
    '/home/chris/' 
    >>> path_insensitive('/home/CHRIS') 
    '/home/chris' 
    >>> path_insensitive('/Home/CHRIS/.gtk-bookmarks') 
    '/home/chris/.gtk-bookmarks' 
    >>> path_insensitive('/home/chris/.GTK-bookmarks') 
    '/home/chris/.gtk-bookmarks' 
    >>> path_insensitive('/HOME/Chris/.GTK-bookmarks') 
    '/home/chris/.gtk-bookmarks' 
    >>> path_insensitive("/HOME/Chris/I HOPE this doesn't exist") 
    "/HOME/Chris/I HOPE this doesn't exist" 
    """ 

    return _path_insensitive(path) or path 


def _path_insensitive(path): 
    """ 
    Recursive part of path_insensitive to do the work. 
    """ 

    if path == '' or os.path.exists(path): 
     return path 

    base = os.path.basename(path) # may be a directory or a file 
    dirname = os.path.dirname(path) 

    suffix = '' 
    if not base: # dir ends with a slash? 
     if len(dirname) < len(path): 
      suffix = path[:len(path) - len(dirname)] 

     base = os.path.basename(dirname) 
     dirname = os.path.dirname(dirname) 

    if not os.path.exists(dirname): 
     dirname = _path_insensitive(dirname) 
     if not dirname: 
      return 

    # at this point, the directory exists but not the file 

    try: # we are expecting dirname to be a directory, but it could be a file 
     files = os.listdir(dirname) 
    except OSError: 
     return 

    baselow = base.lower() 
    try: 
     basefinal = next(fl for fl in files if fl.lower() == baselow) 
    except StopIteration: 
     return 

    if basefinal: 
     return os.path.join(dirname, basefinal) + suffix 
    else: 
     return 
1

खोज एली के लिए एक सरल पुनरावर्ती क्रिया से ऊपर का सुझाव यह है:

def find_sensitive_path(dir, insensitive_path): 

    insensitive_path = insensitive_path.strip(os.path.sep) 

    parts = insensitive_path.split(os.path.sep) 
    next_name = parts[0] 
    for name in os.listdir(dir): 
     if next_name.lower() == name.lower(): 
      improved_path = os.path.join(dir, name) 
      if len(parts) == 1: 
       return improved_path 
      else: 
       return find_sensitive_path(improved_path, os.path.sep.join(parts[1:])) 
    return None 
संबंधित मुद्दे