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.

Siehe auch

Weitere Posts