Come ignorare i file nascosti usando os.listdir ()?


88

Il mio script python viene eseguito in os.listdir(path)cui il percorso è una coda contenente gli archivi che devo trattare uno per uno.

Il problema è che ottengo l'elenco in un array e quindi faccio solo un semplice array.pop(0). Funzionava bene finché non ho messo il progetto in sovversione. Ora ottengo la .svncartella nel mio array e ovviamente la mia applicazione si blocca.

Quindi ecco la mia domanda: esiste una funzione che ignora i file nascosti durante l'esecuzione di un os.listdir()e in caso contrario quale sarebbe il modo migliore?


potresti anche voler evitare le cartelle conos.path.isdir()
HashRocketSyntax

Risposte:


103

Puoi scriverne uno tu stesso:

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

Oppure puoi usare un glob :

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

Uno di questi ignorerà tutti i nomi di file che iniziano con '.'.


1
la funzione proposta listdir_nohiddennon è del tutto compatibile con os.listdir, poiché l'utilizzo di ne yieldfa un generatore. Invece dovrebbe scorrere l'elenco di output os.listdire rimuovere le voci che iniziano con "."
Milo Wielondek

3
@ 0sh: Perché deve rimuovere le cose sul posto? Basta definire una nuova funzione che fa list(listdir_nohidden(path))e quella nuova funzione è esattamente compatibile con os.listdir.
abarnert

50

Questa è una vecchia domanda, ma sembra che manchi l'ovvia risposta dell'uso della comprensione delle liste, quindi la aggiungo qui per completezza:

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

Come nota a margine, lo stato dei documenti listdirrestituirà i risultati in "ordine arbitrario", ma un caso d'uso comune è di averli ordinati alfabeticamente. Se vuoi che i contenuti della directory siano ordinati alfabeticamente senza considerare le maiuscole, puoi usare:

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

5
key=lambda f: f.lower()può essere scritto senza lambda:key=str.lower
Jean-François Fabre

2
Per combinare entrambi:sorted([f for f in os.listdir('./') if not f.startswith('.')], key=str.lower)
Robert

19

Su Windows, Linux e 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
dovrebbe funzionare anche su un Mac, i file nascosti iniziano con "." anche.
Verena Haunschmid

2
Questa è l'unica risposta portatile, ottimo lavoro, ma le altre risposte forniscono un wrapper completo per os.listdir quindi ...[f for f in os.listdir(path) if not folder_is_hidden(f)]
SensorSmith


14

glob :

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

( globafferma di usare listdire fnmatchsotto il cofano, ma controlla anche l'interlinea '.', non usando fnmatch.)


6

Penso che sia troppo faticoso esaminare tutti gli elementi in un ciclo. Preferirei qualcosa di più semplice come questo:

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

Se la directory contiene più di un file nascosto , questo può aiutare:

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

per l'indipendenza dalla piattaforma come ha detto @Josh, il glob funziona bene:

import glob
glob.glob('*')

Funziona solo se hai un file nascosto e ne conosci il nome. Cosa succede se la directory contiene dozzine di file nascosti, con nomi arbitrari che non puoi conoscere in anticipo?
FeRD

Ciao @FeRD, sì. Quando eseguo l'elaborazione batch / backlog su un Mac, inserisco tutti i file in una nuova cartella e .DS_Storevengono creati automaticamente. Quando comprimo tutti i file e lo invio a un server, .DS_Storeviene aggiunto anche. Se sono presenti vari file nascosti, puoi provareos.system('ls -1')
utente 923227

Non multipiattaforma. os.popen('ls -1').read()non funzionerà su Windows. Questo è il punto centrale os.listdir().
FeRD

1
filenames = (f.name for f in os.scandir() if not f.name.startswith('.'))
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.