Python - kolla om en fil är uppdaterad

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Nifelhem
Inlägg: 103
Blev medlem: 16 december 2013, 18:00:39

Python - kolla om en fil är uppdaterad

Inlägg av Nifelhem »

Jag har en mapp med tio textfiler som sparas av ett program på datorn. Jag behöver ta sista raden i varje fil och trolla vidare, men bara när filen är "nysparad".
Jag har en timerlösning som går igenom mappen vid valda intervall. Har lyckats att printa både filnamn och senast ändrad.
Det jag har problem med är jämförelsen av skapat-tidpunkten för varje fil med föregående körning av loopen.

Gå igenom mappen
spara filnamn, skapad-tidpunkt
om ny-skapat-tidpunkt skiljer sig från skapad-tidpunkt :
ta sista raden i den filen och gör något
sätt skapad-tidpunkt för just denna fil = ny-skapd-tidpunkt
vänta en stund och kör igen
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Re: Python - kolla om en fil är uppdaterad

Inlägg av Micke_s »

spara förgående tid i en lista.

filelist ska behållar mellan varje körning.

Kod: Markera allt

#någon slags pseudokod.
def scan():
   changed = []
   for filename in filenames:
      if filname in filelist:
         timestamp = file_update_time(filname)
         if filelist[filename] != timestamp:
            filelist[filename] = timestamp 
            changed.append(filename) #old file updated
      else
         changed.append(filename) # new file found
   return changed
Maalobs
Inlägg: 1299
Blev medlem: 3 februari 2005, 14:35:15
Ort: Stockholm

Re: Python - kolla om en fil är uppdaterad

Inlägg av Maalobs »

Uh, vakna på soffan och stappla upp och läsa forumet i ottan, det är aldrig en bra idé. :hacker:

Python kan jag inte, men här har du ett fungerande exempel i Perl.
Det finns olika sätt att lagra filers datumstämpel.
Men datumstämpeln hör hemma som metadata i filsystemet, så varför inte låta filsystemet lagra det åt dig.

Du kan skapa en tom fil som heter t ex real_filename.txt.previous, som får lagra den förra datumstämpeln för filen real_filename.txt.
Det är vad som händer i scriptet nedan.
Sök på "###" i scriptet för att hitta de detaljer du behöver ändra för dina specifika syften;
1. Sökvägen till mappen där dina datafiler finns.
2. Regular expression som matchar mönstret på dina datafiler (exemplet nedan förväntar sig test01.txt, test02.txt, osv.
3. Platsen där du lägger till vad du vill göra med den sista raden i uppdaterade datafiler.

Scriptet kan schemaläggas i operativsystemet, jag skulle hellre göra så än att wrappa allt i en while(1) { ... } oändlig loop och ha scriptet permanent körande med en sleep(60); längst ner.
På tal om operativsystem så nämnde du aldrig vad det var, men det här funkar på både Linux/BSD/OSX och på Windows NT t o m Windows 10.

Kod: Markera allt

#!/usr/bin/perl
use strict;
use warnings;

### Set the correct path here to your folder with datafiles:
my $folder = '/path/to/my/folder';

my ($datafile, $prevfile);
my $prev_missing = 0;

opendir my $dh, $folder or die "Can't open '$folder': $!\n";
while (defined($_ = readdir $dh)) {
	# Only process relevant files.
	next unless ($_ =~ m/^test\d\d\.txt$/); ### Set the correct filename pattern of your datafiles here.

	$datafile = $folder . '/' . $_;
	$prevfile = $folder . '/' . $_ . '.previous';

	# Read modified time of the datafile.
	my ($data_mtime) = (stat $datafile)[9];

	# Create a date reference file if none exists.
	unless (-e $prevfile) {
		# Create an empty file, only filesystem metadata will be used.
		open my $prev_fh, '>', $prevfile or die "Can't open '$prevfile' for writing: $!\n";
		print $prev_fh '';
		close $prev_fh;

		# Set modified time on prevfile to that of datafile.
		utime(time, $data_mtime, $prevfile);

		# All of the above can be replaced by this:
		#system(qq(touch -r "$datafile" "$prevfile"));

		# Set flag to indicate that prevfile was missing, so last line of datafile will still be processed.
		$prev_missing = 1;

		print "Created file:\n$prevfile\n";
	}

	# Read modified time of the prevfile.
	my ($prev_mtime) = (stat $prevfile)[9];

	# Process current datafile if it is newer than the prevfile, or if the flag has been set to indicate first execution.
	if ($data_mtime > $prev_mtime or $prev_missing == 1) {
		open my $data_fh, '<', $datafile or die "Can't open '$datafile' for reading: $!\n";
		foreach my $lastline (reverse <$data_fh>) {
			# Remove CR/LF/CRLF.
			chomp $lastline;
			
			print "File:\n$datafile\n";
			print "Last line:\n'$lastline'\n\n";
			### Do something useful with $lastline here.
			
			last;
		}
		close $data_fh;

		# Set modified time on prevfile to that of datafile.
		utime(time, $data_mtime, $prevfile);
		
		# Unset flag.
		$prev_missing = 0;
	}
}
closedir $dh;
Kanske funkar att ha som mall för att skriva om i Python, om inte annat. :)

Notera att programmet touch i Linux/BSD/OSX kan användas för att förenkla scriptet, du kan ange den riktiga filen som referens, samma kommando både skapar en tom fil om den saknas, och sätter datumstämpeln till samma värde som på referensfilen, och finns filen redan så uppdateras bara datumstämpeln på den:

Kod: Markera allt

touch -r real_filename.txt real_filename.txt.previous
Använder du det och har mellanslag i sökvägen eller filnamnen, då får du komma ihåg att wrappa filnamnen i citat-tecken på kommandoraden, se exemplet i den bortkommenterade raden i scriptet.
Nifelhem
Inlägg: 103
Blev medlem: 16 december 2013, 18:00:39

Re: Python - kolla om en fil är uppdaterad

Inlägg av Nifelhem »

Jag tackar för visat engagemang: Det var ju inte meningen att väcka folk på en lördagsmorgon. :ledsen:

Jag har kommit en bit längre med detta. för mig var det dict (och en natts sömn) som var lösningen. Klistrar in koden ifall någon skulle råka surfa in. Tror att det funkar. Har inte tillgång till systemet som genererar filerna nu. Får se om jag har ork att skriva en snutt som genererar filer samtidigt som detta script kollar.

Kod: Markera allt

#!/usr/bin/python
# -*- coding: ISO-8859-1  -*-

import os
import time
from threading import Timer
from time import sleep
os.system("cls")


def check():
	for key in original_dict:
		# print (key) #test
		if original_dict.get(key) < os.path.getmtime(key):
			print ("File {} has been modified".format(f))
			original_dict[key] = os.path.getmtime(key)
		else:
			print ("No changes, going to sleep.")	
			
	t = Timer(5,check)
	t.start()

	
original_dict={}

for files in os.listdir():
	if files[0]=="L" and files[-3:]=="TXT": #kollar om första tecknet i filnamnet är L och sista 3 är txt
		original_dict[files] = os.path.getmtime(files) #lägger till filnamn: skapad-tid i en dictionary

t = Timer(5, check)
t.start() # after 5 seconds check

# timer will wake up every 10 seconds, while we do something else
while True:
	print ("do something else")
	sleep(10)
mounte
Inlägg: 204
Blev medlem: 14 november 2010, 13:15:00
Ort: Sandviken

Re: Python - kolla om en fil är uppdaterad

Inlägg av mounte »

Beroende på vilket OS du vill köra på så finns olika metoder att lyssna på förändringar i filsystemet utan att manuellt polla efter förändringar.
Linux har t.ex. inotify som du kan använda med pyinotify
https://github.com/seb-m/pyinotify/wiki/Tutorial

i windows så kan du använda win32-anrop
http://timgolden.me.uk/python/win32_how ... anges.html

Sedan finns följande bibliotek som väljer metod beroende på os.
https://pypi.org/project/watchdog/
guckrum
Inlägg: 1669
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Python - kolla om en fil är uppdaterad

Inlägg av guckrum »

Timestamp känns skakigt. Jag förslår att du lutar dig mot "tail" som fungerat deterministiskt i väldigt många år. Det gör jag.
Se denna https://stackoverflow.com/questions/125 ... -in-python.
Nifelhem
Inlägg: 103
Blev medlem: 16 december 2013, 18:00:39

Re: Python - kolla om en fil är uppdaterad

Inlägg av Nifelhem »

Tack för kompletterande svar. :)
Har lyckats fånga den sista raden i respektive log-fil nu. Nästa steg bli att försöka skicka de raderna till en annan dator i samma lokala nätverk. Har absolut noll koll men har börjat att läsa på om sockets, TCP, meddelandeköer mm.
Skulle jag få till ett någotsånär fungerande variant på detta så ska jag kolla igenom tipsen igen. Det såg intressant ut.
sm7tix
Inlägg: 283
Blev medlem: 19 september 2013, 10:47:03
Ort: Kristianstad

Re: Python - kolla om en fil är uppdaterad

Inlägg av sm7tix »

Dela ut en katalog på den ena och montera på den andra.

.
Nifelhem
Inlägg: 103
Blev medlem: 16 december 2013, 18:00:39

Re: Python - kolla om en fil är uppdaterad

Inlägg av Nifelhem »

Menar du så enkelt som molnet och dropbox?
Eller ännu enklare med windows egna funktioner?
:humm:
sm7tix
Inlägg: 283
Blev medlem: 19 september 2013, 10:47:03
Ort: Kristianstad

Re: Python - kolla om en fil är uppdaterad

Inlägg av sm7tix »

Du delar ut med tex protokollet NFS. Finns enkla howto på nätet. Om det är två Linux maskiner. Annars Samba som funkar med Windows.

.
brrmek
Inlägg: 51
Blev medlem: 26 maj 2012, 23:27:37
Ort: Ursviken

Re: Python - kolla om en fil är uppdaterad

Inlägg av brrmek »

SCP eller RCP är väl bra. Secure copy eller remote copy.
https://pypi.org/project/scp/
Nifelhem
Inlägg: 103
Blev medlem: 16 december 2013, 18:00:39

Re: Python - kolla om en fil är uppdaterad

Inlägg av Nifelhem »

Kollar länkar och funderar. För att vara lite tydligare:

Dator med win 7
Loggar händelser från 10 st. indata. Dessa händelser sker med c:a 30-60 sek intervall.
Data lagras som en rad i en .txt-fil. En fil för varje indataström. (Log n.txt).
Ovanstående går inte ändra på.

Lokalt nätverk.
(rapplig anslutning mot internet)

Dator med Win 10H
Slutmål är att kunna hantera / visa data på valfritt format.

Läser vidare...
Skriv svar