/blog/perl


substr() in Perl
[154170 mal gelesen]
foreach in Perl
[129166 mal gelesen]
Arrays in Perl - Besonderheiten
[125384 mal gelesen]
split() in Perl - Zeichenketten teilen
[113580 mal gelesen]
open() - Dateien öffnen in Perl
[108992 mal gelesen]
grep - Listen durchsuchen in Perl
[94729 mal gelesen]
chomp() in Perl
[93643 mal gelesen]
push in Perl
[90859 mal gelesen]
sleep in Perl - Das aktuelle Script warten lassen
[75984 mal gelesen]
index() in Perl - Zeichenkette in Zeichenkette suchen
[59577 mal gelesen]


Arrays
Dateien
HTPC
Hashes
Leistungsoptimiert
PHP
Perl
RegEx
Schleifen
Script
Skalare
Sonstiges
System
Webserver
Zur Startseite


Mittwoch, 9.1.2008, 21:59:18 Uhr

Wie viele Zeilen hat die Datei?


So ne kleinere Spielerei nebenbei, aber auch hübsch, um zu sehen, was Perl so kann: Wie viele zeilen hat eine Datei?

Man will also wissen, wie viele Zeilen in einer Datei stehen, gesucht wird eine möglichst effektive und Speicherschonende Möglichkeit, dies herauszufinden.

Variante 1: Datei einlesen und zählen
Man liest also die Datei komplett ein und läßt die zeilen zählen, etwa so

open (my $in,'<','test.txt');
@zeilen= <$in>;
close $in;

$zeilenanzahl=@zeilen;
print "Die Datei hat $zeilen Zeilen";



Ja, das geht, aber: Wenn die Datei mehrere Megabyte oder sogar Gigabyte hat, wirds dem Rechner ein bißchen viel...
Die ganze Datei einlesen ist also schon mal blöd.

Ha, Idee, Zeilen nacheinander einlesen:


$zeilen=0;
open (my $in,'<','test.txt');
while (<$in>){$zeilen++;}
close $in;

$zeilenanzahl=@zeilen;
print "Die Datei hat $zeilen Zeilen";



Bingo, geht auch und liest nur einzelne Zeilen ein. Aber Vorsicht: Wenn eine Zeile mehrere MB oder gar GB hat, wirds dem Rechner auch wieder ein bißchen viel, denn pro Zeile wird die aktuelle Zeile $_ zugeordnet, also eingelesen!

Also schon schön, aber nicht perfekt...

Besser gehts so:


open (my $in,'<','test.txt');

$cou += tr/\n/\n/ while read ($in,$_,1024000);

close $in;
print "Die Datei hat $cou Zeilen";


Was passiert hier?
Die Datei wird geöffnet.

Danach wir per read jeweils ein Datenblock von einem Megabyte in $_ eingelesen und die darin enthaltenen \n's gezählt (tr /\n/\n/) und $cou hinzugefügt.

Wieso ist das nun besser?
Weil immer nur maximal ein MB Daten eingelesen werden. Auf Wunsch kann man den Puffer natürlich verkleinern oder vergrößern...


Man sollte es immer vermeiden, Dateien komplett einzulesen, wenn es geht. Sehr lange Dateien können, wenn sie in den Rechnerspeicher eingelesen werden, den Rechner so ziemlich lahm legen!

In diesem Sinne, bis zum nächsten Mal...





Kommentare zum Beitrag "Wie viele Zeilen hat die Datei?"

Kommentar von Renée Bäcker
Wenn es nur um das "Zählen" mit tr/// geht, kannst Du den Ersetzungsteil leer lassen, also

tr/\n//

Solange keine Modifier (tr/\n//cd o.ä.) angegeben werden, wird nichts ersetzt sondern nur gezählt. So geräts Du nicht in Gefahr, durch einen Tippfehler alles zu ersetzen (tr/\n/n/).

Kommentar von Struppi
Warum nicht einfach:

open FH, "test.txt";
while(<FH>){}
print "Zeilen $.";
close FH;


Kommentar von Admin
Nunja, wie ich oben bereits geschrieben habe, wird auch bei
while (<in>){}
die Datei komplett in den Speicher eingelesen. Zwar zeilenweise, aber was, wenn eine Zeile mal 'nen GB hat?
Und um das nachzuvollziehen, kann man ja mal 'ne 1 GB-Datei anlegen, wobei das eine GB in nur einer Zeile steht, also ohne breaks.
Diese eine Zeile liest man dann mal ein... und geht dann Kaffee kochen. Also bei mir hier dauerte es mehrere Minuten, bis sich Perl wieder zurückmeldete, der Systemspeicher ging unterwegs auf 10 MB herunter... in einem 2 GB-System mit Windows. Dabei ging die Prozessorauslastung auf 70 % hoch und die Festplatte lief sich tot... nun, so gehts jedenfalls nicht, da man nie weiss, was man so einlesen muß.

Im Gegensatz dazu brauchte "meine" Methode 3 Sekunden und der Rechner blieb cool. Besser, denke ich...

Kommentar von Struppi
Na gut, wenn du GB grosse Dateien ohne Newline Zeichen hast, dann ist das sicher richtig (wobei das Problem nicht an Perl liegt, sondern am OS). Bei mir kommen solche Dateien selten vor (im Grunde nie).

Realistischer ist z.b. das man die Anzahl der Zeilen in einem Logfile herausfinden möchte, also extrem viele Zeilen mit ca. 100 Zeichen.

Jetzt mach mal einen Benchmark, deine Lösung braucht bei 100.000 Zeilen braucht bei mir sechsmal so lange und je mehr Zeilen umso schlechter wird das Verhältnis.

Also man sollte sich vorher überlegen, ob man Dateien hat, die extrem lange Zeilen haben könnten, dann wäre deine Lösung optimal, bei normal langen Zeilen ist sie langsam.

Kommentar von Peter
finde den Blog gut, habe aber einen Fehler entdeckt in
"Wie viele Zeilen hat die Datei"

Statt:
$zeilenanzahl=@zeilen;
print "Die Datei hat $zeilen Zeilen";
muss es heißen:
$zeilenanzahl=@zeilen;
print "Die Datei hat $zeilenzahl Zeilen";



Thema: Perl

Der Beitrag "Wie viele Zeilen hat die Datei?" wurde 13056 mal gelesen.

Kommentar schreiben  Druckansicht  Seitenanfang 
Beurteilen 






 Zufällige Beiträge im /blog/perl

Wiederholungen finden mit regulären Ausdrücken

chomp() in Perl

Reguläre Ausdrücke in Perl - Kürzeste Variante finden

time - Zeit in Sekunden in Perl

Doppelte Elemente aus Array entfernen - Und die Reihenfolge beibehalten!

Was man mit RegEx tun sollte und was nicht - Reguläre Ausdrücke

Keys eines Hashes feststellen in Perl

Datei komplett einlesen - Die exotische Variante

Alle Dateien eines Verzeichnisses löschen - Aber bitte mit Ausnahmen!

Bestimmte Dateien eines Ordners suchen - Aus der Praxis - Suchen nach Dateiendung



0.0241339206695557 sec. to build



...Blogsoftware in pure Perl - Powered by a lot of Coffee...


SSD-Festplatte - Wassn das???
Die Transliteration - Nur ein Zeichen in einem Skalar ersetzen
Select - Case in Perl
Windows 7 XP Mode – Wo finde ich den XP-Modus unter Windows 7?
Mac-Adresse beim Apple Macintosh herausfinden
SGN-Funktion für Perl

Eigene IP herausfinden mit Perl
Epoche live in Datum umwandeln
Firefox 3 - Exe-Files downloaden


Gesamtverzeichnis
Februar 2010
Dezember 2009
Oktober 2009
Januar 2009
Dezember 2008
November 2008
September 2008
August 2008
Juli 2008
Juni 2008
Mai 2008
April 2008
Januar 2008
Dezember 2007
November 2007
Oktober 2007
September 2007
August 2007
Juni 2007
Mai 2007
April 2007
März 2007
Februar 2007
Januar 2007
Dezember 2006


Mister Wong

RSS-Feed

Heute ist der
23.11.2024

Es ist
15:43:20 Uhr

Ihre IP:
3.16.70.99

Blog-Einträge: 186

Die letzten 24 Stunden im Überblick


Gelesene Beiträge insgesamt:
4423991


Webseiten vergleichen
Kalender mit Feiertagen - 2028
Links finden und testen
Menschliche Datumsangaben
IP zu Domain herausfinden
Time live in Datum umwandeln
Perl für Windows



Impressum