Como posso iterar sobre arquivos em um determinado diretório?

555

Eu preciso percorrer todos os .asmarquivos dentro de um determinado diretório e executar algumas ações neles.

Como isso pode ser feito de maneira eficiente?

Itzik984
fonte

Respostas:

807

Resposta original:

import os

for filename in os.listdir(directory):
    if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
        continue
    else:
        continue

Versão Python 3.6 da resposta acima, usando os- assumindo que você tenha o caminho do diretório como um strobjeto em uma variável chamada directory_in_str:

import os

directory = os.fsencode(directory_in_str)

for file in os.listdir(directory):
     filename = os.fsdecode(file)
     if filename.endswith(".asm") or filename.endswith(".py"): 
         # print(os.path.join(directory, filename))
         continue
     else:
         continue

Ou recursivamente, usando pathlib:

from pathlib import Path

pathlist = Path(directory_in_str).glob('**/*.asm')
for path in pathlist:
     # because path is object not string
     path_in_str = str(path)
     # print(path_in_str)
anselm
fonte
1
Isso apenas parece listar os diretórios ou arquivos imediatamente em um diretório. A resposta de pedromateo abaixo parece fazer uma listagem recursiva.
Jay Sheth
8
Observe que no diretório Python 3.6 é esperado que esteja em bytes e o listdir cuspirá uma lista de nomes de arquivos também no tipo de dados bytes, para que você não possa executar o endswith diretamente nele. Esse bloco de código deve ser alterado paradirectory = os.fsencode(directory_in_str) for file in os.listdir(directory): filename = os.fsdecode(file) if filename.endswith(".asm") or filename.endswith(".py"): # print(os.path.join(directory, filename)) continue else: continue
Kim Stacks
13
print(os.path.join(directory, filename))necessidade de ser alterado para print(os.path.join(directory_in_str, filename))obtê-lo para trabalhar em python 3.6
Hugo Koopmans
54
Se você estiver vendo isso em 2017 ou além, os.scandir (dir_str) agora está disponível e é muito mais limpo de usar. Não há necessidade de fsencode. for entry in os.scandir(path): print(entry.path)
cabra
2
Prefere if filename.endswith((".asm", ".py")):aif filename.endswith(".asm") or filename.endswith(".py"):
Maroloccio
152

Isso irá percorrer todos os arquivos descendentes, não apenas os filhos imediatos do diretório:

import os

for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        #print os.path.join(subdir, file)
        filepath = subdir + os.sep + file

        if filepath.endswith(".asm"):
            print (filepath)
pedromateo
fonte
3
Uma referência para a função os.walk pode ser encontrada nos seguintes documentos: docs.python.org/2/library/os.path.html#os.path.walk
ScottMcC
136

Você pode tentar usar o módulo glob :

import glob

for filepath in glob.iglob('my_dir/*.asm'):
    print(filepath)

e desde o Python 3.5, você também pode pesquisar subdiretórios:

glob.glob('**/*.txt', recursive=True) # => ['2.txt', 'sub/3.txt']

Dos documentos:

O módulo glob encontra todos os nomes de caminho que correspondem a um padrão especificado de acordo com as regras usadas pelo shell Unix, embora os resultados sejam retornados em ordem arbitrária. Nenhuma expansão de til é feita, mas os intervalos de caracteres *,? E expressos com [] serão correspondidos corretamente.

Doboy
fonte
19

Desde o Python 3.5, as coisas são muito mais fáceis com os.scandir ( )

with os.scandir(path) as it:
    for entry in it:
        if entry.name.endswith(".asm") and entry.is_file():
            print(entry.name, entry.path)

O uso de scandir () em vez de listdir () pode aumentar significativamente o desempenho do código que também precisa de informações sobre o tipo ou o atributo do arquivo, porque os objetos os.DirEntry expõem essas informações se o sistema operacional fornecer essas informações ao varrer um diretório. Todos os métodos os.DirEntry podem executar uma chamada do sistema, mas is_dir () e is_file () geralmente requerem apenas uma chamada do sistema para links simbólicos; os.DirEntry.stat () sempre requer uma chamada do sistema no Unix, mas apenas uma para links simbólicos no Windows.

crypdick
fonte
entryé um posix.DirEntry tipo com um grupo de métodos úteis, tais como entry.is_dir(), is_file(),is_symlink()
crypdick
17

O Python 3.4 e posterior oferecem pathlib na biblioteca padrão. Você poderia fazer:

from pathlib import Path

asm_pths = [pth for pth in Path.cwd().iterdir()
            if pth.suffix == '.asm']

Ou se você não gosta de compreensões de lista:

asm_paths = []
for pth in Path.cwd().iterdir():
    if pth.suffix == '.asm':
        asm_pths.append(pth)

Path objetos podem ser facilmente convertidos em strings.

Greg
fonte
9

Aqui está como eu repito os arquivos no Python:

import os

path = 'the/name/of/your/path'

folder = os.fsencode(path)

filenames = []

for file in os.listdir(folder):
    filename = os.fsdecode(file)
    if filename.endswith( ('.jpeg', '.png', '.gif') ): # whatever file types you're using...
        filenames.append(filename)

filenames.sort() # now you have the filenames and can do something with them

NENHUM DESTES TÉCNICAS GARANTE QUALQUER PEDIDO DE ITERAÇÃO

Sim, super imprevisível. Observe que eu ordeno os nomes dos arquivos, o que é importante se a ordem dos arquivos for importante, ou seja, para quadros de vídeo ou coleta de dados dependente do tempo. Lembre-se de colocar índices nos seus nomes de arquivos!

Daniel McGrath
fonte
Nem sempre classificado ... im1, im10, im11 ..., im2 ... Abordagem útil , caso contrário. from pkg_resources import parse_versione filenames.sort(key=parse_version)fez isso.
Hastur
5

Você pode usar glob para consultar o diretório e a lista:

import glob
import os

#to get the current working directory name
cwd = os.getcwd()
#Load the images from images folder.
for f in glob.glob('images\*.jpg'):   
    dir_name = get_dir_name(f)
    image_file_name = dir_name + '.jpg'
    #To print the file name with path (path will be in string)
    print (image_file_name)

Para obter a lista de todos os diretórios da matriz, você pode usar os :

os.listdir(directory)
YAP
fonte
4

Ainda não estou muito satisfeito com essa implementação, queria ter um construtor personalizado que faça DirectoryIndex._make(next(os.walk(input_path)))isso para que você possa simplesmente passar o caminho para o qual deseja uma listagem de arquivos. Edições bem-vindas!

import collections
import os

DirectoryIndex = collections.namedtuple('DirectoryIndex', ['root', 'dirs', 'files'])

for file_name in DirectoryIndex(*next(os.walk('.'))).files:
    file_path = os.path.join(path, file_name)
ThorSummoner
fonte
2

Eu realmente gosto de usar a scandirdiretiva que está embutida na osbiblioteca. Aqui está um exemplo de trabalho:

import os

i = 0
with os.scandir('/usr/local/bin') as root_dir:
    for path in root_dir:
        if path.is_file():
            i += 1
            print(f"Full path is: {path} and just the name is: {path.name}")
print(f"{i} files scanned successfully.")
jamescampbell
fonte
resposta duplicada
crypdick 31/08/19