Preciso obter o arquivo mais recente de uma pasta usando python. Enquanto estiver usando o código:
max(files, key = os.path.getctime)
Estou recebendo o erro abaixo:
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'a'
Preciso obter o arquivo mais recente de uma pasta usando python. Enquanto estiver usando o código:
max(files, key = os.path.getctime)
Estou recebendo o erro abaixo:
FileNotFoundError: [WinError 2] The system cannot find the file specified: 'a'
Respostas:
O que for atribuído à files
variável está incorreto. Use o seguinte código.
import glob
import os
list_of_files = glob.glob('/path/to/folder/*') # * means all if need specific format then *.csv
latest_file = max(list_of_files, key=os.path.getctime)
print latest_file
if os.path.isdir(latest_file):
pathlib.Path
objetos mais do que strings e os.path. Com pathlib.Path objetos sua resposta torna-se: list_of_paths = folder_path.glob('*'); latest_path = max(list_of_paths, key=lambda p: p.stat().st_ctime)
os.path.getctime
como chave, mesmo com Path
objetos.
max(files, key = os.path.getctime)
é um código bastante incompleto. O que é files
? Provavelmente é uma lista de nomes de arquivos, saindo de os.listdir()
.
Mas esta lista lista apenas as partes do nome do arquivo (também conhecidas como "nomes de base"), porque seu caminho é comum. Para usá-lo corretamente, você deve combiná-lo com o caminho que leva a ele (e usado para obtê-lo).
Como (não testado):
def newest(path):
files = os.listdir(path)
paths = [os.path.join(path, basename) for basename in files]
return max(paths, key=os.path.getctime)
if basename.endswith('.csv')
na lista de compreensão.
Eu sugeriria usar em glob.iglob()
vez de glob.glob()
, pois é mais eficiente.
glob.iglob () Retorna um iterador que gera os mesmos valores que glob () sem realmente armazená-los todos simultaneamente.
Que significa glob.iglob()
que será mais eficiente.
Geralmente uso o código abaixo para encontrar o arquivo mais recente correspondente ao meu padrão:
LatestFile = max(glob.iglob(fileNamePattern),key=os.path.getctime)
NOTA: Existem variantes de max
função. No caso de encontrar o arquivo mais recente, usaremos a variante abaixo:
max(iterable, *[, key, default])
que precisa ser iterável, portanto seu primeiro parâmetro deve ser iterável. No caso de encontrar o máximo de nums, podemos usar a variante beow:max (num1, num2, num3, *args[, key])
max()
tipo. No meu caso, usei um diferente, key=os.path.basename
pois os nomes dos arquivos tinham registros de data e hora.
Tente classificar itens por hora de criação. O exemplo abaixo classifica os arquivos em uma pasta e obtém o primeiro elemento mais recente.
import glob
import os
files_path = os.path.join(folder, '*')
files = sorted(
glob.iglob(files_path), key=os.path.getctime, reverse=True)
print files[0]
Não tenho a reputação de comentar, mas o ctime da resposta de Marlon Abeykoons não deu o resultado correto para mim. Usar o mtime faz o truque. (chave = os.path.get m tempo))
import glob
import os
list_of_files = glob.glob('/path/to/folder/*') # * means all if need specific format then *.csv
latest_file = max(list_of_files, key=os.path.getmtime)
print latest_file
Encontrei duas respostas para esse problema:
python os.path.getctime max não retorna a última diferença entre python - getmtime () e getctime () no sistema unix
(Editado para melhorar a resposta)
Primeiro defina uma função get_latest_file
def get_latest_file(path, *paths):
fullpath = os.path.join(path, paths)
...
get_latest_file('example', 'files','randomtext011.*.txt')
Você também pode usar uma docstring!
def get_latest_file(path, *paths):
"""Returns the name of the latest (most recent) file
of the joined path(s)"""
fullpath = os.path.join(path, *paths)
Se você usa o Python 3 , pode usar o iglob .
Código completo para retornar o nome do arquivo mais recente:
def get_latest_file(path, *paths):
"""Returns the name of the latest (most recent) file
of the joined path(s)"""
fullpath = os.path.join(path, *paths)
files = glob.glob(fullpath) # You may use iglob in Python3
if not files: # I prefer using the negation
return None # because it behaves like a shortcut
latest_file = max(files, key=os.path.getctime)
_, filename = os.path.split(latest_file)
return filename
JuniperAccessLog-standalone-FCL_VPN
papel?
Eu tentei usar as sugestões acima e meu programa travou, então eu descobri que o arquivo que estou tentando identificar foi usado e ao tentar usar 'os.path.getctime' ele travou. o que finalmente funcionou para mim foi:
files_before = glob.glob(os.path.join(my_path,'*'))
**code where new file is created**
new_file = set(files_before).symmetric_difference(set(glob.glob(os.path.join(my_path,'*'))))
esse código obtém o objeto incomum entre os dois conjuntos de listas de arquivos não é o mais elegante e, se vários arquivos forem criados ao mesmo tempo, provavelmente não será estável
Um método muito mais rápido no Windows (0.05s), chame um script bat que faça isso:
get_latest.bat
@echo off
for /f %%i in ('dir \\directory\in\question /b/a-d/od/t:c') do set LAST=%%i
%LAST%
onde \\directory\in\question
é o diretório que você deseja investigar.
get_latest.py
from subprocess import Popen, PIPE
p = Popen("get_latest.bat", shell=True, stdout=PIPE,)
stdout, stderr = p.communicate()
print(stdout, stderr)
se encontrar um arquivo stdout
é o caminho estderr
é Nenhum.
Use stdout.decode("utf-8").rstrip()
para obter a representação de sequência utilizável do nome do arquivo.
ls -Art | tail -n 1
. Avalie o desempenho de uma solução antes de fazer reivindicações sobre ela.
Eu tenho usado isso no Python 3, incluindo correspondência de padrões no nome do arquivo.
from pathlib import Path
def latest_file(path: Path, pattern: str = "*"):
files = path.glob(pattern)
return max(files, key=lambda x: x.stat().st_ctime)