Wie ignoriere ich versteckte Dateien mit os.listdir ()?


87

Mein Python-Skript führt eine aus, os.listdir(path)bei der der Pfad eine Warteschlange mit Archiven ist, die ich einzeln behandeln muss.

Das Problem ist, dass ich die Liste in einem Array bekomme und dann einfach eine mache array.pop(0). Es hat gut funktioniert, bis ich das Projekt in Subversion versetzt habe. Jetzt bekomme ich den .svnOrdner in mein Array und natürlich stürzt meine Anwendung ab.

Hier ist meine Frage: Gibt es eine Funktion, die versteckte Dateien bei der Ausführung eines ignoriert os.listdir()und wenn nicht, was wäre der beste Weg?

Antworten:


102

Sie können selbst eine schreiben:

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

Oder Sie können einen Glob verwenden :

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

In beiden Fällen werden alle Dateinamen ignoriert, die mit beginnen '.'.


1
Die vorgeschlagene Funktion listdir_nohiddenist nicht ganz kompatibel mit os.listdir, da die Verwendung von yieldes zu einem Generator macht. Stattdessen sollte es die Ausgabeliste von durchlaufen os.listdirund Einträge entfernen, die mit '.' Beginnen.
Milo Wielondek

3
@ 0sh: Warum muss es Dinge an Ort und Stelle entfernen? Definieren Sie einfach eine neue Funktion, die list(listdir_nohidden(path))genau funktioniert und mit der diese neue Funktion genau kompatibel ist os.listdir.
Abarnert

47

Dies ist eine alte Frage, aber es scheint, als ob die offensichtliche Antwort auf die Verwendung des Listenverständnisses fehlt. Der Vollständigkeit halber füge ich sie hier hinzu:

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

Nebenbei bemerkt, der Dokumentstatus listdirgibt die Ergebnisse in "beliebiger Reihenfolge" zurück. Ein häufiger Anwendungsfall ist jedoch, sie alphabetisch sortieren zu lassen. Wenn Sie möchten, dass der Verzeichnisinhalt ohne Berücksichtigung der Groß- und Kleinschreibung alphabetisch sortiert wird, können Sie Folgendes verwenden:

sorted([f for f in os.listdir('./')], key=lambda f: f.lower())

5
key=lambda f: f.lower()kann ohne Lambda geschrieben werden:key=str.lower
Jean-François Fabre

2
Um beides zu kombinieren:sorted([f for f in os.listdir('./') if not f.startswith('.')], key=str.lower)
Robert

18

Unter Windows, Linux und 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

2
sollte auch auf einem Mac funktionieren, versteckte Dateien beginnen dort mit '.' auch.
Verena Haunschmid

2
Dies ist die einzige tragbare Antwort, großartige Arbeit, aber die anderen Antworten bieten einen vollständigen Wrapper für os.listdir, also ...[f for f in os.listdir(path) if not folder_is_hidden(f)]
SensorSmith


14

glob :

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

( globbehauptet zu verwenden listdirund fnmatchunter der Haube, aber es prüft auch auf eine Führung '.', nicht durch Verwendung fnmatch.)


6

Ich denke, es ist zu viel Arbeit, alle Elemente in einer Schleife durchzugehen. Ich würde etwas Einfacheres wie dieses bevorzugen:

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

Wenn das Verzeichnis mehr als eine versteckte Datei enthält , kann dies helfen:

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

Für die Plattformunabhängigkeit, wie @Josh erwähnte, funktioniert der Glob gut:

import glob
glob.glob('*')

Das funktioniert nur, wenn Sie eine versteckte Datei haben und den Namen kennen. Was ist, wenn das Verzeichnis Dutzende versteckter Dateien mit beliebigen Namen enthält, die Sie nicht im Voraus kennen?
FeRD

Hallo @FeRD, ja. Wenn ich eine Batch- / Backlog-Verarbeitung auf einem Mac durchführe, lege ich alle Dateien in einen neuen Ordner und werde .DS_Storeautomatisch erstellt. Wenn ich alle Dateien komprimiere und auf einen Server schiebe, wird .DS_Storeauch hinzugefügt. Wenn es verschiedene versteckte Dateien gibt, können Sie versuchenos.system('ls -1')
Benutzer 923227

Nicht plattformübergreifend. os.popen('ls -1').read()funktioniert nicht unter Windows. Das ist der springende Punkt os.listdir().
FeRD

1
filenames = (f.name for f in os.scandir() if not f.name.startswith('.'))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.