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?

Talnicolas
quelle

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 '.'.

Adam Rosenfield
quelle
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())
Joshmaker
quelle
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
cle
quelle
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
15

Joshmaker hat die richtige Lösung für Ihre Frage.
Wie ignoriere ich versteckte Dateien mit os.listdir ()?

In Python 3 wird jedoch empfohlen, pathlib anstelle von os zu verwenden.

from pathlib import Path 
visible_files = [
    file for file in Path(".").iterdir() if not file.name.startswith(".")
]
Abschaum
quelle
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.)

Josh Lee
quelle
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('*')
Benutzer 923227
quelle
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('.'))
Amenbo
quelle