Como você obtém uma listagem de diretório classificada por data de criação em python?

129

Qual é a melhor maneira de obter uma lista de todos os arquivos em um diretório, classificados por data [criada | modificado], usando python, em uma máquina Windows?

Liza
fonte

Respostas:

79

Atualização : para classificar dirpathas entradas por data de modificação no Python 3:

import os
from pathlib import Path

paths = sorted(Path(dirpath).iterdir(), key=os.path.getmtime)

(coloque a resposta da @ Pygirl aqui para maior visibilidade)

Se você já possui uma lista de nomes de arquivos files, classifique-a no local pela hora da criação no Windows:

files.sort(key=os.path.getctime)

A lista de arquivos que você pode obter, por exemplo, usando globcomo mostrado na resposta de @ Jay .


resposta antiga Aqui está uma versão mais detalhada da @Greg Hewgillresposta de . É o mais compatível com os requisitos da pergunta. Faz uma distinção entre datas de criação e modificação (pelo menos no Windows).

#!/usr/bin/env python
from stat import S_ISREG, ST_CTIME, ST_MODE
import os, sys, time

# path to the directory (relative or absolute)
dirpath = sys.argv[1] if len(sys.argv) == 2 else r'.'

# get all entries in the directory w/ stats
entries = (os.path.join(dirpath, fn) for fn in os.listdir(dirpath))
entries = ((os.stat(path), path) for path in entries)

# leave only regular files, insert creation date
entries = ((stat[ST_CTIME], path)
           for stat, path in entries if S_ISREG(stat[ST_MODE]))
#NOTE: on Windows `ST_CTIME` is a creation date 
#  but on Unix it could be something else
#NOTE: use `ST_MTIME` to sort by a modification date

for cdate, path in sorted(entries):
    print time.ctime(cdate), os.path.basename(path)

Exemplo:

$ python stat_creation_date.py
Thu Feb 11 13:31:07 2009 stat_creation_date.py
jfs
fonte
1
Isso funcionou perfeitamente. Estou tentando comparar dois diretórios cdate uns com os outros. Existe uma maneira de comparar os segundos entre os dois cdates?
Federer
@malcmcmul: cdateé um número flutuante de segundos desde a época.
JFS
4
Isso funciona, mas a solução mais sucinta está em stackoverflow.com/a/4500607/68534
jmoz
@jmoz: você quer dizer como este . A solução que você vinculou está errada: não filtra arquivos regulares. Nota: minha solução chama statuma vez por dir.entry.
JFS
Perdoe-me, o link fornecido por Sabastian é ainda mais sucinto! Obrigado.
jmoz
148

Eu fiz isso no passado para um script Python para determinar os últimos arquivos atualizados em um diretório:

import glob
import os

search_dir = "/mydir/"
# remove anything from the list that is not a file (directories, symlinks)
# thanks to J.F. Sebastion for pointing out that the requirement was a list 
# of files (presumably not including directories)  
files = list(filter(os.path.isfile, glob.glob(search_dir + "*")))
files.sort(key=lambda x: os.path.getmtime(x))

Isso deve fazer o que você procura com base no arquivo mtime.

EDIT : Observe que você também pode usar os.listdir () no lugar de glob.glob (), se desejar - a razão pela qual usei glob no meu código original foi porque estava querendo usar glob para procurar apenas arquivos com um conjunto específico de extensões de arquivo, para qual glob () era mais adequado. Para usar o listdir, veja como seria:

import os

search_dir = "/mydir/"
os.chdir(search_dir)
files = filter(os.path.isfile, os.listdir(search_dir))
files = [os.path.join(search_dir, f) for f in files] # add path to each file
files.sort(key=lambda x: os.path.getmtime(x))
Jay
fonte
glob () é bom, mas lembre-se de que ele pula arquivos que começam com um ponto. Os sistemas * nix tratam esses arquivos como ocultos (omitindo-os das listagens), mas no Windows eles são arquivos normais.
Efotinis 03/10/08
Essas soluções não excluem dirs da lista.
Constantin
Sua solução os.listdir está ausente nos os.path.join: files.sort (lambda x, y: cmp (os.path.getmtime (os.path.getmtime (os.path.join (search_dir, x)), os.path.getmtime (os .path.join (search_dir, y))))
Peter Hoffmann
files.sort(key=lambda fn: os.path.getmtime(os.path.join(search_dir, fn)))
JFS
22
Um mero files.sort(key=os.path.getmtime)deve funcionar (sem lambda).
JFS
31

Há uma os.path.getmtimefunção que fornece o número de segundos desde a época e deve ser mais rápida que os.stat.

import os 

os.chdir(directory)
sorted(filter(os.path.isfile, os.listdir('.')), key=os.path.getmtime)
Gypaetus
fonte
23

Aqui está a minha versão:

def getfiles(dirpath):
    a = [s for s in os.listdir(dirpath)
         if os.path.isfile(os.path.join(dirpath, s))]
    a.sort(key=lambda s: os.path.getmtime(os.path.join(dirpath, s)))
    return a

Primeiro, criamos uma lista dos nomes dos arquivos. isfile () é usado para pular diretórios; pode ser omitido se diretórios devem ser incluídos. Em seguida, classificamos a lista no local, usando a data de modificação como chave.

efotinis
fonte
Classificou-o pelo mais antigo primeiro ao mais recente. Quando eu queria que os 5 arquivos mais recentes que eu tinha que fazer o seguintea[-5:]
Daniel Butler
20

Aqui está uma frase:

import os
import time
from pprint import pprint

pprint([(x[0], time.ctime(x[1].st_ctime)) for x in sorted([(fn, os.stat(fn)) for fn in os.listdir(".")], key = lambda x: x[1].st_ctime)])

Isso chama os.listdir () para obter uma lista dos nomes de arquivos e, em seguida, chama os.stat () para que cada um obtenha o tempo de criação e depois classifica o tempo de criação.

Observe que esse método chama os.stat () apenas uma vez para cada arquivo, o que será mais eficiente do que chamá-lo para cada comparação em uma classificação.

Greg Hewgill
fonte
isso é dificilmente pitônico, embora resolva o trabalho (aviso: não testou o código).
Adriano Varoli Piazza
Esta solução não exclui dirs da lista.
Constantin
@ Constantin: isso é verdade, mas uma rápida [... se stat.S_ISREG (x)] resolveria isso.
Greg Hewgill 04/10/08
16

Sem alterar o diretório:

import os    

path = '/path/to/files/'
name_list = os.listdir(path)
full_list = [os.path.join(path,i) for i in name_list]
time_sorted_list = sorted(full_list, key=os.path.getmtime)

print time_sorted_list

# if you want just the filenames sorted, simply remove the dir from each
sorted_filename_list = [ os.path.basename(i) for i in time_sorted_list]
print sorted_filename_list
Nic
fonte
12

Em python 3.5 ou superior

from pathlib import Path
sorted(Path('.').iterdir(), key=lambda f: f.stat().st_mtime)
ignorante
fonte
3
para a data de criação, use em seu f.stat().st_ctimelugar.
Alanjds 7/08/19
11

Aqui está minha resposta usando glob sem filtro, se você quiser ler arquivos com uma certa extensão em ordem de data (Python 3).

dataset_path='/mydir/'   
files = glob.glob(dataset_path+"/morepath/*.extension")   
files.sort(key=os.path.getmtime)
dinos66
fonte
5
# *** the shortest and best way ***
# getmtime --> sort by modified time
# getctime --> sort by created time

import glob,os

lst_files = glob.glob("*.txt")
lst_files.sort(key=os.path.getmtime)
print("\n".join(lst_files))
Arash
fonte
por favor fornecer o contexto
Claire
"melhor" é subjetivo. Sua resposta seria melhor se você explicasse por que acha que é o melhor caminho.
Bryan Oakley
Se você quer "o melhor", certamente não usa glob, pois é muito lento.
user136036
4
sorted(filter(os.path.isfile, os.listdir('.')), 
    key=lambda p: os.stat(p).st_mtime)

Você pode usar em os.walk('.').next()[-1]vez de filtrar com os.path.isfile, mas isso deixa links simbólicos mortos na lista e os.statfalhará neles.

Alex Coventry
fonte
4
from pathlib import Path
import os

sorted(Path('./').iterdir(), key=lambda t: t.stat().st_mtime)

ou

sorted(Path('./').iterdir(), key=os.path.getmtime)

ou

sorted(os.scandir('./'), key=lambda t: t.stat().st_mtime)

onde m hora é hora modificada.

Pygirl
fonte
1

este é um passo básico para aprender:

import os, stat, sys
import time

dirpath = sys.argv[1] if len(sys.argv) == 2 else r'.'

listdir = os.listdir(dirpath)

for i in listdir:
    os.chdir(dirpath)
    data_001 = os.path.realpath(i)
    listdir_stat1 = os.stat(data_001)
    listdir_stat2 = ((os.stat(data_001), data_001))
    print time.ctime(listdir_stat1.st_ctime), data_001
cumulus_13
fonte
1

A resposta de Alex Coventry produzirá uma exceção se o arquivo for um link simbólico para um arquivo inexistente, o código a seguir corrige essa resposta:

import time
import datetime
sorted(filter(os.path.isfile, os.listdir('.')), 
    key=lambda p: os.path.exists(p) and os.stat(p).st_mtime or time.mktime(datetime.now().timetuple())

Quando o arquivo não existe, now () é usado e o link simbólico irá para o final da lista.

Paolo Benvenuto
fonte
0

Aqui estão algumas linhas simples que procuram por extensão e fornecem uma opção de classificação

def get_sorted_files(src_dir, regex_ext='*', sort_reverse=False): 
    files_to_evaluate = [os.path.join(src_dir, f) for f in os.listdir(src_dir) if re.search(r'.*\.({})$'.format(regex_ext), f)]
    files_to_evaluate.sort(key=os.path.getmtime, reverse=sort_reverse)
    return files_to_evaluate
TXN_747
fonte
0

Para completar com os.scandir(2x mais rápido pathlib):

import os
sorted(os.scandir('/tmp/test'), key=lambda d: d.stat().st_mtime)
n1nj4
fonte
0

Esta foi a minha versão:

import os

folder_path = r'D:\Movies\extra\new\dramas' # your path
os.chdir(folder_path) # make the path active
x = sorted(os.listdir(), key=os.path.getctime)  # sorted using creation time

folder = 0

for folder in range(len(x)):
    print(x[folder]) # print all the foldername inside the folder_path
    folder = +1
haqrafiul
fonte
No meu código, os arquivos são classificados do mais antigo para o mais novo. Para obter os nomes de arquivos ou pastas mais recentes primeiro, você precisa adicionar reverse = True na lista de arquivos (no meu caso, era x). Então, x = classificado (os.listdir (), chave = os.path.getctime, reverse = True)
haqrafiul
-6

Talvez você deva usar comandos shell. No Unix / Linux, a localização com classificação provavelmente será capaz de fazer o que você deseja.

stephanea
fonte