Имя файла без учета регистра в Python? - PullRequest
9 голосов
/ 11 декабря 2011

Мне нужно загрузить файл по его имени, но имя, которое я получаю, не чувствительно к регистру. «A.txt» на самом деле может быть «a.txt». Как сделать это быстрым способом (не генерировать все возможные имена и пробовать каждое)?

Ответы [ 4 ]

7 голосов
/ 11 декабря 2011

Вы можете перечислить каталог, в котором находится файл (os.listdir), и посмотреть, есть ли совпадения для вашего имени файла. Сопоставление может быть сделано в нижнем регистре как имен файлов и сравнения.

5 голосов
/ 11 декабря 2011

Вы не можете сделать это, не взяв список каталогов и не сравнив элемент данных, который вы ищете, и каждый элемент в каталоге. Файловая система чувствительна к регистру, и это все, что нужно сделать.

Вот функция (ну, две), которую я написал, чтобы сделать это полностью, сопоставляя имя файла нечувствительным образом, рекурсивно: 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
2 голосов
/ 08 июня 2016

Это простая рекурсивная функция для поиска, который Eli предлагает выше:

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
1 голос
/ 11 декабря 2011

Составьте список каталогов; и создайте словарь, содержащий сопоставление имен файлов в верхнем регистре с именами файлов в фактическом регистре. Затем введите заглавные буквы и найдите их в словаре.

...