Jak zignorować ukryte pliki za pomocą os.listdir ()?

88

Mój skrypt w Pythonie wykonuje operację, w os.listdir(path)której ścieżka jest kolejką zawierającą archiwa, które muszę pojedynczo traktować.

Problem polega na tym, że otrzymuję listę w tablicy, a następnie po prostu robię proste array.pop(0). Działało dobrze, dopóki nie umieściłem projektu w wywrotce. Teraz mam .svnfolder w mojej tablicy i oczywiście powoduje to awarię mojej aplikacji.

Oto moje pytanie: czy istnieje funkcja, która ignoruje ukryte pliki podczas wykonywania, os.listdir()a jeśli nie, to jaki byłby najlepszy sposób?

talnicolas
źródło
możesz także chcieć uniknąć folderów zos.path.isdir()
HashRocketSyntax,

Odpowiedzi:

103

Możesz sam napisać:

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

Lub możesz użyć globu :

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

Każde z nich zignoruje wszystkie nazwy plików zaczynające się od '.'.

Adam Rosenfield
źródło
1
proponowana funkcja listdir_nohiddennie jest do końca kompatybilna os.listdir, ponieważ użycie yieldpowoduje, że jest ona generatorem. Zamiast tego powinien przeglądać listę wyników os.listdiri usuwać wpisy zaczynające się od „.”
Milo Wielondek
3
@ 0sh: Dlaczego musi usuwać rzeczy na miejscu? Po prostu zdefiniuj nową funkcję, która to robi list(listdir_nohidden(path))i ta nowa funkcja jest dokładnie zgodna z os.listdir.
abarnert
50

To jest stare pytanie, ale wygląda na to, że brakuje w nim oczywistej odpowiedzi na temat używania funkcji rozumienia list, więc dodam je tutaj dla kompletności:

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

Na marginesie, stan docs listdirzwróci wyniki w „dowolnej kolejności”, ale częstym przypadkiem użycia jest sortowanie alfabetyczne. Jeśli chcesz, aby zawartość katalogu była posortowana alfabetycznie bez użycia wielkich liter, możesz użyć:

sorted([f for f in os.listdir('./')], key=lambda f: f.lower())
Joshmaker
źródło
5
key=lambda f: f.lower()można zapisać bez lambdy:key=str.lower
Jean-François Fabre
2
Aby połączyć oba:sorted([f for f in os.listdir('./') if not f.startswith('.')], key=str.lower)
Robert
19

W systemach Windows, Linux i 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
źródło
2
powinien również działać na komputerze Mac, ukryte pliki zaczynają się tam od „.” także.
Verena Haunschmid
2
To jedyna przenośna odpowiedź, świetna robota, ale inne odpowiedzi zapewniają pełne opakowanie dla os.listdir, więc ...[f for f in os.listdir(path) if not folder_is_hidden(f)]
SensorSmith
15

Joshmaker ma właściwe rozwiązanie na Twoje pytanie.
Jak zignorować ukryte pliki za pomocą os.listdir ()?

Jednak w Pythonie 3 zaleca się używanie pathlib zamiast os.

from pathlib import Path 
visible_files = [
    file for file in Path(".").iterdir() if not file.name.startswith(".")
]
szumowiny
źródło
14

glob :

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

( globtwierdzi, że używa listdiri fnmatchpod maską, ale sprawdza również prowadzenie '.', a nie za pomocą fnmatch.)

Josh Lee
źródło
6

Myślę, że przeglądanie wszystkich elementów w pętli wymaga zbyt wiele pracy. Wolałbym coś prostszego:

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

Jeśli katalog zawiera więcej niż jeden ukryty plik , może to pomóc:

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

dla niezależności platformy, jak wspomniał @Josh, glob działa dobrze:

import glob
glob.glob('*')
użytkownik 923227
źródło
Działa to tylko wtedy, gdy masz jeden ukryty plik i znasz jego nazwę. A co jeśli katalog zawiera dziesiątki ukrytych plików o dowolnych nazwach, których nie możesz z góry poznać?
FeRD
Cześć @FeRD, tak. Kiedy wykonuję przetwarzanie wsadowe / zaległości na komputerze Mac, umieszczam wszystkie pliki w nowym folderze i .DS_Storesą tworzone automatycznie. Kiedy spakuję wszystkie pliki i wypchnę je na serwer, .DS_Storerównież zostaną dodane. Jeśli istnieją różne ukryte pliki, możesz spróbowaćos.system('ls -1')
użytkownik 923227
Nie dla wielu platform. os.popen('ls -1').read()nie będzie działać w systemie Windows. O to właśnie chodzi os.listdir().
FeRD
1
filenames = (f.name for f in os.scandir() if not f.name.startswith('.'))
amenbo
źródło