2011-12-11 44 views
8

Tôi cần tải một tệp cho tên của nó, nhưng tên tôi nhận được không phân biệt chữ hoa chữ thường. "A.txt" thực sự có thể là "a.txt". Làm thế nào để làm điều này một cách nhanh chóng (không tạo ra tất cả các tên có thể và thử mỗi)?Tên tệp không phân biệt chữ hoa chữ thường?

+0

gì os là bạn không? – vdbuilder

+0

Không quan trọng, tên tôi nhận được (phân biệt chữ hoa chữ thường) được phân tích cú pháp từ tệp tập lệnh. –

+0

Hệ điều hành (và thực sự là hệ thống tập tin) chắc chắn có liên quan ở đây. – Johnsyweb

Trả lời

6

Bạn có thể liệt kê thư mục của tệp trong (os.listdir) và xem có phù hợp với tên tệp của bạn hay không. Việc kết hợp có thể được thực hiện bằng cách viết hoa cả tên tệp và so sánh.

+0

Vâng, nhưng nó có hiệu quả không? Xem xét các thư mục có thể có hàng ngàn tập tin? –

+4

@ user975135: Tôi sẽ không lo lắng về sự kém hiệu quả cho đến khi bạn thử phương pháp này và nó quá chậm đối với nhu cầu của bạn. – dreamlax

+0

Vâng, tôi đã xử lý hàng ngàn chuỗi cùng một lúc với Python trước đây vì vậy tôi nghĩ rằng tôi không nên bỏ qua nó nếu có một cách khác. –

1

Tạo danh sách thư mục; và tạo một từ điển có chứa một ánh xạ các tên tập tin cao hơn cho các tên tập tin thực tế của chúng. Sau đó, tạo chữ hoa đầu vào của bạn và tìm trong từ điển.

5

Bạn không thể thực hiện việc này mà không cần lấy danh sách thư mục và lấy cả mục bạn đang tìm kiếm và mỗi mục trong thư mục vào một trường hợp phổ biến để so sánh. Hệ thống tệp phân biệt chữ hoa chữ thường và đó là tất cả.

Đây là chức năng (tốt, hai) mà tôi đã viết để làm điều đó hoàn toàn, khớp với tên tệp theo cách không nhạy cảm, đệ quy: 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

Đây là một hàm đệ quy đơn giản để vào tìm kiếm Eli gợi ý ở trên:

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 
Các vấn đề liên quan