Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]389[/thread]

NUR letzte Zeile in einem Textdokument auswerten

Leser: 3


<< >> 9 Einträge, 1 Seite
oruebe
 2004-12-23 19:09
#3856 #3856
User since
2004-07-09
46 Artikel
BenutzerIn
[default_avatar]
Hallo,

ich habe Textdateien mit unterschiedlich vielen Zeilen.

Wie kann ich NUR die letzte Zeile zur weiteren Bearbeitung herausbekommen?

Z.B
open(DATEI,"meine_Datei.dat");
$letzteZeile= ?;
close(DATEI);

Gibt es hierfür einen Befehl? Und wie kann ich sicherstellen, dass die letzte Zeile nicht leer ist, bzw. in diesem Falle die vorletzte Zeile nehmen?

Danke für ALLE Hilfe und frohe Weihnachten,
Oliver\n\n

<!--EDIT|oruebe|1103821847-->
ptk
 2004-12-23 19:18
#3857 #3857
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
CPAN:File::ReadBackwards. Tie::File wuerde auch gehen, ist aber bei weiten nicht so effizient.
oruebe
 2004-12-23 19:34
#3858 #3858
User since
2004-07-09
46 Artikel
BenutzerIn
[default_avatar]
schnell wie immer :-)

Aber wo füge ich das ein? Und: wenn ich das richtig verstehe, dreht das ja den Inhal nur um, oder? Muss ich nicht irgendwie auch noch sagen WAS (bzw. welche Datei) gedreht werden soll? Oder bin ich gerade völlig auf dem Holzweg?
ptk
 2004-12-23 19:42
#3859 #3859
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Einfach die SYNOPSIS von File::ReadBackwards abschreiben. Der erste Rueckgabewert des getline-Aufrufes ist es.
jemand
 2004-12-23 20:17
#3860 #3860
User since
2004-05-14
231 Artikel
BenutzerIn
[default_avatar]
Wieso nicht mit ganz normalem Code??
ich würde hier mal folgendes ausprobieren:
Code: (dl )
1
2
3
4
5
my @zeilen = <DATEI>;
close(DATEI);

$zeilenanzahl = @zeilen;
my $letzteZeile = @zeilen[$zeilenanzahl];


dann muss man nur noch mit nem regexp prüfen ob in der zeile was steht.
wenn nichts drinsteht nimmt man --$zeilenanzahl.
dann nochmalprüfen usw. in ner schleife am besten die halt dann abgebrochen wird wenn was drinsteht...
print uc 'i',chr(29*4).q+'s +.++($_=q-m-),++$_;
print chr for 116,$_[0],97,$_[0],98;
print 'ug,',chr(), scalar reverse qq?!erutaef a s'ti?;
Relais
 2004-12-23 21:10
#3861 #3861
User since
2003-08-06
2254 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=jemand,23.12.2004, 19:17]ich würde hier mal folgendes ausprobieren:
Code: (dl )
1
2
3
4
5
my @zeilen = <DATEI>;
close(DATEI);

$zeilenanzahl = @zeilen;
my $letzteZeile = @zeilen[$zeilenanzahl];
[/quote]
Oh, hättste es mal getan! =)

Der Code ist mehr als falsch, er funktioniert auch nicht.

Der Index der Letzten Position in einem Array ist die Zahl seiner Elemente minus 1. Das liegt daran, daß die Elemente eines Arrays mit 0 losgezählt werden, 5 Elemente hätten also die Indizes 0 .. 4.

Ein Arrayelement wird in Perl mit $arrayname[INDEX] angesprochen, INDEX ist eine Zahl. Diese Zahl kann komische Formen annehmen, oder auch in einer Variable stehen.

Die folgenden Wege gehen gut:
Code: (dl )
1
2
3
4
5
6
7
my $letzte_zeile = pop @zeilen;
# oder auch
$letzte_zeile = $zeilen[ -1 ];
# oder auch
$letzte_zeile = $zeilen[ $#zeilen ];
# oder auch
$letzte_zeile = $zeilen[ $zeilenzahl - 1 ];
Erst denken, dann posten --
27. Deutscher Perl- u. Raku -Workshop 12. bis 14. Mai 2025 in München.

Winter is Coming
esskar
 2004-12-23 21:35
#3862 #3862
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
@jemand:
kostet zu viel speicher...

mein vorschlag, ohne (nicht.standard) modul

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use Fcntl;

sub get_lastline_of_file
{
  my ($file) = @_;

  my $fh;
  return undef unless open($fh, "< $file");

  binmode $fh;
  seek($fh, 0, SEEK_END);
 
  my $size = tell($fh);
  my $rest = $size;
  my $step = 256;

  my $retval = "";
  while($rest > 0)
  {
     my $buffer;
     my $len = $step > $size ? $size : $step;
     seek($fh, -$len, SEEK_CUR);

     unless(read($fh, $buffer, $len))
     {
        close $fh;
        die "Read failed unexpected.";
     }    

     my $pos = rindex($buffer, "\n");
     while($pos > -1)
     {
        if(($pos != -1 + length $buffer) or ($rest != $size))
        {
           return substr($buffer, $pos+1).$retval;
        }
        $pos = rindex($buffer, "\n", $pos);
     }

     $retval = $buffer.$retval;
     $rest -= $len;
  }

  return $retval;
}


hab es jetzt nicht getestet; aber könnte so gehen!\n\n

<!--EDIT|esskar|1103830645-->
renee
 2004-12-24 14:05
#3863 #3863
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
unter Unix könnte man es doch auch einfacher machen:
Code: (dl )
my $last_line = `tail -1 $filename`;
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
esskar
 2004-12-24 14:08
#3864 #3864
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
[quote=renee,24.12.2004, 13:05]unter Unix könnte man es doch auch einfacher machen:
Code: (dl )
my $last_line = `tail -1 $filename`;
[/quote]
hmm;
extra einen prozess starten?
<< >> 9 Einträge, 1 Seite



View all threads created 2004-12-23 19:09.