Dateien rückwärts lesen
Veröffentlicht von Thomas Fahle am (Permalink)
Fall 1: Kleine Dateien
Falls die Datei klein ist, kann man sie einfach komplett in ein Array einlesen und dieses mit reverse() umdrehen.
#!/usr/bin/perl use strict; use warnings; my $file = 'test.txt'; my @zeilen_rueckwaerts = (); open (FH, '<', $file) or die "Fehler open() $!"; @zeilen_rueckwaerts = reverse <FH>; close(FH) or die "Fehler close() $!"; my $zeile = ''; foreach $zeile (@zeilen_rueckwaerts) { # Zeilenenden wie in der eingelesenen Datei print $zeile; }
Angewandt auf die Beispieldatei test.txt
Zeile 01 Zeile 02 Zeile 03 Zeile 04 Zeile 05
ergibt sich folgende Ausgabe:
Zeile 05 Zeile 04 Zeile 03 Zeile 02 Zeile 01
Fall 2: Große Dateien
Das CPAN-Modul File::ReadBackwards kann auch mit sehr großen Dateien umgehen. Die Datei muss nicht in den Hauptspeicher passen.
#!/usr/bin/perl use warnings; use strict; use File::ReadBackwards ; my $file = 'test.txt'; my $bw = File::ReadBackwards->new( $file ) or die "can't read $file $!" ; my $line = ''; while( defined( $line = $bw->readline ) ) { # Zeilenenden wie in der eingelesenen Datei print $line ; } exit();
File::ReadBackwards ist nicht gedacht, um Änderungen in einer Datei zu verfolgen, dafür gibt es File::Tail.
Rückwärts suchen
Das nachfolgende Beispiel durchsucht eine Datei rückwärts, d.h. die Suche beginnt in der letzten Zeile, und stoppt sobald der erste Treffer erzielt wurde. Das ist sehr praktisch, wenn man in einer Log-Datei nach dem neuesten Ereignis suchen möchte.
#!/usr/bin/perl use warnings; use strict; use File::ReadBackwards ; my $file = 'test.txt'; my $bw = File::ReadBackwards->new( $file ) or die "can't read $file $!" ; my $line = ''; my $suchbegriff = '03'; while( defined( $line = $bw->readline ) ) { print "Bearbeite $line"; if ( $line =~ /$suchbegriff/) { print "Treffer: $line" ; # Suche beenden last; } }
Das Programm erzeugt folgende Ausgabe
Bearbeite Zeile 05 Bearbeite Zeile 04 Bearbeite Zeile 03 Treffer: Zeile 03
Caveats
File::ReadBackwards (Version 1.04) unterstützt flock() nicht. Es kann also vorkommen, daß die letzte Zeile nicht komplett zurückgegeben wird. Dies hängt auch von der Größe des Dateipuffers des Betriebssystems und der Anzahl der Prozesse, die gerade in die Datei schreiben, ab.