Como ignorar arquivos ocultos usando os.listdir ()?


87

Meu script python executa um os.listdir(path)onde o caminho é uma fila contendo arquivos que preciso tratar um por um.

O problema é que estou colocando a lista em uma matriz e então faço um simples array.pop(0). Estava funcionando bem até que coloquei o projeto em subversão. Agora eu pego a .svnpasta em meu array e, claro, isso faz meu aplicativo travar.

Portanto, aqui está a minha pergunta: existe uma função que ignora os arquivos ocultos ao executar um os.listdir()e se não, qual seria a melhor maneira?

Respostas:


102

Você mesmo pode escrever um:

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

Ou você pode usar um glob :

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

Qualquer um deles irá ignorar todos os nomes de arquivo que começam com '.'.


1
a função proposta listdir_nohiddennão é totalmente compatível com os.listdir, já que o uso de a yieldtorna um gerador. Em vez disso, ele deve percorrer a lista de saída os.listdire remover as entradas que começam com '.'
Milo Wielondek de

3
@ 0sh: Por que é necessário remover as coisas no local? Basta definir uma nova função que o faça list(listdir_nohidden(path))e com a qual essa nova função seja exatamente compatível os.listdir.
abarnert

47

Esta é uma pergunta antiga, mas parece que está faltando a resposta óbvia de usar a compreensão de lista, então estou adicionando aqui para completar:

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

Como uma observação lateral, o estado docs listdirretornará resultados em 'ordem arbitrária', mas um caso de uso comum é classificá-los em ordem alfabética. Se você deseja que o conteúdo do diretório seja classificado em ordem alfabética sem considerar a capitalização, você pode usar:

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

5
key=lambda f: f.lower()pode ser escrito sem lambda:key=str.lower
Jean-François Fabre

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

18

No 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
também deve funcionar em um Mac, os arquivos ocultos começam com '.' também.
Verena Haunschmid

2
Esta é a única resposta portátil, ótimo trabalho, mas as outras respostas fornecem um invólucro completo para os.listdir, então ...[f for f in os.listdir(path) if not folder_is_hidden(f)]
SensorSmith


14

glob :

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

( globafirma usar listdire por fnmatchbaixo do capô, mas também verifica se há uma guia '.', não usando fnmatch.)


6

Eu acho que é muito trabalhoso passar por todos os itens em um loop. Eu preferiria algo mais simples como isto:

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

Se o diretório contiver mais de um arquivo oculto , isso pode ajudar:

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

para independência de plataforma, como @Josh mencionou, o glob funciona bem:

import glob
glob.glob('*')

Isso funciona apenas se você tiver um arquivo oculto e souber o nome dele. E se o diretório contiver dezenas de arquivos ocultos, com nomes arbitrários que você não pode saber com antecedência?
FeRD

Olá @FeRD, sim. Quando estou fazendo processamento em lote / backlog em um mac, coloco todos os arquivos em uma nova pasta e .DS_Storeé criado automaticamente. Ao compactar todos os arquivos e enviá-los para um servidor, .DS_Storetambém é adicionado. Se houver vários arquivos ocultos, você pode tentaros.system('ls -1')
usuário 923227 de

Não é multiplataforma. os.popen('ls -1').read()não funcionará no Windows. Esse é o ponto principal de os.listdir().
FeRD

1
filenames = (f.name for f in os.scandir() if not f.name.startswith('.'))
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.