Как игнорировать скрытые файлы с помощью os.listdir ()?

87

Мой скрипт python выполняет, os.listdir(path)где путь - это очередь, содержащая архивы, которые мне нужно обрабатывать один за другим.

Проблема в том, что я получаю список в виде массива, а затем просто выполняю простой array.pop(0). Он работал нормально, пока я не поставил проект на подрывную работу. Теперь я получаю .svnпапку в своем массиве, и, конечно же, это вызывает сбой моего приложения.

Итак, вот мой вопрос: есть ли функция, которая игнорирует скрытые файлы при выполнении, os.listdir()и если нет, что было бы лучшим способом?

талниколас
источник

Ответы:

102

Вы можете написать сами:

def listdir_nohidden(path):
    for f in os.listdir(path):
        if not f.startswith('.'):
            yield f

Или вы можете использовать глобус :

def listdir_nohidden(path):
    return glob.glob(os.path.join(path, '*'))

Любой из них проигнорирует все имена файлов, начинающиеся с '.'.

Адам Розенфилд
источник
1
Предлагаемая функция listdir_nohiddenне совсем совместима с os.listdir, так как использование yieldделает ее генератором. Вместо этого он должен просмотреть список вывода os.listdirи удалить записи, начинающиеся с '.'
Milo Wielondek
3
@ 0sh: Почему он должен убирать вещи на месте? Просто определите новую функцию, которая работает list(listdir_nohidden(path))и с которой она точно совместима os.listdir.
abarnert 05
47

Это старый вопрос, но похоже, что ему не хватает очевидного ответа об использовании понимания списка, поэтому я добавляю его здесь для полноты:

[f for f in os.listdir(path) if not f.startswith('.')]

В качестве побочного примечания, состояние документов listdirбудет возвращать результаты в «произвольном порядке», но общий вариант использования - их сортировка в алфавитном порядке. Если вы хотите, чтобы содержимое каталога было отсортировано по алфавиту без использования заглавных букв, вы можете использовать:

sorted([f for f in os.listdir('./')], key=lambda f: f.lower())
Джошмейкер
источник
5
key=lambda f: f.lower()можно написать без лямбды:key=str.lower
Жан-Франсуа Фабр
2
Чтобы объединить оба:sorted([f for f in os.listdir('./') if not f.startswith('.')], key=str.lower)
Роберт
18

В Windows, Linux и OS X:

if os.name == 'nt':
    import win32api, win32con


def folder_is_hidden(p):
    if os.name== 'nt':
        attribute = win32api.GetFileAttributes(p)
        return attribute & (win32con.FILE_ATTRIBUTE_HIDDEN | win32con.FILE_ATTRIBUTE_SYSTEM)
    else:
        return p.startswith('.') #linux-osx
cle
источник
2
также должен работать на Mac, скрытые файлы начинаются там с '.' также.
Верена Хауншмид
2
Это единственный переносимый ответ, отличная работа, но другие ответы предоставляют полную оболочку для os.listdir, так что ...[f for f in os.listdir(path) if not folder_is_hidden(f)]
SensorSmith
14

glob :

>>> import glob
>>> glob.glob('*')

( globутверждает, что использует listdirи fnmatchпод капотом, но также проверяет наличие интерлиньяжа '.', а не с помощью fnmatch.)

Джош Ли
источник
6

Я думаю, что перебирать все элементы в цикле - это слишком большая работа. Я бы предпочел что-нибудь попроще:

lst = os.listdir(path)
if '.DS_Store' in lst:
    lst.remove('.DS_Store')

Если в каталоге содержится более одного скрытого файла , это может помочь:

all_files = os.popen('ls -1').read()
lst = all_files.split('\n')

для независимости платформы, поскольку @Josh упомянул, что glob работает хорошо:

import glob
glob.glob('*')
пользователь 923227
источник
Это работает, только если у вас есть один скрытый файл и вы знаете его имя. Что делать, если в каталоге есть десятки скрытых файлов с произвольными именами, которые вы не можете знать заранее?
FeRD
Привет @FeRD, да. Когда я выполняю пакетную обработку / обработку невыполненных работ на Mac, я помещаю все файлы в новую папку и .DS_Storeавтоматически создается. Когда я заархивирую все файлы и отправляю их на сервер, .DS_Storeтоже добавляется. Если есть различные скрытые файлы, возможно, вы можете попробоватьos.system('ls -1')
пользователь 923227
Не кроссплатформенный. os.popen('ls -1').read()не будет работать в Windows. В этом весь смысл os.listdir().
FeRD
1
filenames = (f.name for f in os.scandir() if not f.name.startswith('.'))
аменбо
источник