Datei teilweise einlesen
Sascha
- perl
0 Christian Kruse0 Struppi0 Christian Kruse
0 Jonny0 Jonny
Hallo,
ich habe eine Text-Datei mit Mitgliederinformationen (feste Feldlängen).
Nun habe ich ein kleines Perl proggi welches diese Datei einliest, unnötige Felder rauslöscht, Leerzeichen am Satzende entfernt, ein Semikolon als Trennzeichen einfügt und dann unter anderem Namen abspeichert.
Nun hat sich die Eingangsdatei dramatisch vergrößert (Text-Datei hat etwa 930 MB, ca. 2.5 Mil. Zeilen).
Es sollen nun mehrere Ausgangsdateien geschrieben werden, die erste z.B. von Mitglied 00000001 - 00100000, die nächste von 00100001 - 00200000 usw....
Mein altes Proggi bringt meinen Rechner gnadenlos in den Speicherüberlauf.
Wie kann ich es nun schaffen, das nur der erste Block an Daten eingelsen wird, korregiert und abgespeichert wird, und dann der nächste Block erst wieder an der Stelle anfängt einzulesen an der der erste Block zu ende war?
Kann ich einen offset einstellen (ich weiss ja z.B. das eine Zeile immer genau 422 Zeichen besteht)?
Danke für alle Tips!
Sascha
你好 Sascha,
Mein altes Proggi bringt meinen Rechner gnadenlos in den Speicherüberlauf.
Vermutlich, weil du ein “@lines = <FILE>”-Konstrukt hast? Sinnvoller waere
da ein
while(my $line = <FILE>) {
# mach was mit $line
}
Wie kann ich es nun schaffen, das nur der erste Block an Daten eingelsen
wird, korregiert und abgespeichert wird, und dann der nächste Block
erst wieder an der Stelle anfängt einzulesen an der der erste Block zu
ende war?
Kann ich einen offset einstellen (ich weiss ja z.B. das eine Zeile immer
genau 422 Zeichen besteht)?
Ich glaube, du suchst seek und tell.
再见,
CK
Hallo
你好 Sascha,
Mein altes Proggi bringt meinen Rechner gnadenlos in den Speicherüberlauf.
Vermutlich, weil du ein “@lines = <FILE>”-Konstrukt hast? Sinnvoller waere
da einwhile(my $line = <FILE>) {
# mach was mit $line
}
...Das war mein erster Fehler...
Wie kann ich es nun schaffen, das nur der erste Block an Daten eingelsen
wird, korregiert und abgespeichert wird, und dann der nächste Block
erst wieder an der Stelle anfängt einzulesen an der der erste Block zu
ende war?
Kann ich einen offset einstellen (ich weiss ja z.B. das eine Zeile immer
genau 422 Zeichen besteht)?Ich glaube, du suchst seek und tell.
再见,
CK
AHA! Genau nachdem habe ich gesucht. Habe es auch gleich ausprobiert. Klappt prima, BIS AUF DIESEN FEHLER: die erste Datei stimmt einwandfrei, bei der 2. Datei fehlt die 1. Zeile! Der Datensatz ist dann in keiner der beiden Dateien vorhanden!
Hab hier mal ein Auszug von dem wie es etwa bei mir aussieht:
sysopen (DATEI, $data2 , O_RDONLY);
while(<DATEI>)
{
#Felder definieren, korregieren usw...
if ($feld1 <= $dat1) #1er Block
{push(@NeueZeilen,$neu);}
else # Block 1 zuende
{$pos = tell (DATEI); close (DATEI);}
}
open(DAT, ">$dfs1") # Schreibe Ausgangsdatei 1
print DAT @NeueZeilen;
close (DAT);
sysopen (DATEI, $data2 , O_RDONLY);
seek (DATEI,$pos,0); # Position setzen
while(<DATEI>)
{
#Felder definieren, korregieren usw...
if ($feld1 <= $dat1) #2er Block
{push(@NeueZeilen,$neu);}
else {$pos = tell (DATEI); close (DATEI);}
}
open(DAT, ">$dfs2") # Schreibe Ausgangsdatei 2
print DAT @NeueZeilen;
close (DAT);
Woran liegt das ??? Ich habe auch schon von $pos-1 probiert, das war es aber nicht :-)
Danke
Sascha
Hab hier mal ein Auszug von dem wie es etwa bei mir aussieht:
sysopen (DATEI, $data2 , O_RDONLY);
while(<DATEI>)
{
#Felder definieren, korregieren usw...
if ($feld1 <= $dat1) #1er Block
{push(@NeueZeilen,$neu);}
else # Block 1 zuende
{$pos = tell (DATEI); close (DATEI);}
}
Du pushst hier evtl. 900MB in den Speicher. Warum?
Du kannst ohne Probleme zwei Dateien gleichzeitig öffnen (oder mehr), eine zum lesen und eine zum schreiben.
Struppi.
Du pushst hier evtl. 900MB in den Speicher. Warum?
Keine Ahnung...
Du kannst ohne Probleme zwei Dateien gleichzeitig öffnen (oder mehr), eine zum lesen und eine zum schreiben.
ist geändert! Jetzt hab ich nur noch das Problem das mir durch das tell und seek eine Zeile fehlt???!!!
Sascha
ist geändert! Jetzt hab ich nur noch das Problem das mir durch das tell und seek eine Zeile fehlt???!!!
Ich weiß nicht warum du seek und tell brauchst.
du liest Datei A ein und schreibst die Zeilen die du brauchst in B, da ist gar keine Notwendigkeit für seek oder tell - oder?
Struppi.
Ich weiß nicht warum du seek und tell brauchst.
du liest Datei A ein und schreibst die Zeilen die du brauchst in B, da ist gar keine Notwendigkeit für seek oder tell - oder?
Tja manchmal sieht man den Wald vor lauter Bäumen nicht!
Jetzt klappt, war doch ganz einfach.-)
Danke
ich habe eine Text-Datei mit Mitgliederinformationen (feste Feldlängen).
Bei der Größe solltest du dir dringend überlegen ob du nicht auf eine Datenbank wechseln willst.
Nun habe ich ein kleines Perl proggi welches diese Datei einliest, unnötige Felder rauslöscht, Leerzeichen am Satzende entfernt, ein Semikolon als Trennzeichen einfügt und dann unter anderem Namen abspeichert.
Nun hat sich die Eingangsdatei dramatisch vergrößert (Text-Datei hat etwa 930 MB, ca. 2.5 Mil. Zeilen).
Es sollen nun mehrere Ausgangsdateien geschrieben werden, die erste z.B. von Mitglied 00000001 - 00100000, die nächste von 00100001 - 00200000 usw....
Mein altes Proggi bringt meinen Rechner gnadenlos in den Speicherüberlauf.
Naja, du musst die Datei ja nicht im ganzen einlesen, sondern jede Zeile einzeln bearbeiten und dann in eine Temporäre Datei schreiben und am Ende die alte löschen die Temporäre Datei umbennen.
Danke für alle Tips!
Eine richtige DB wäre wohl sinvoller.
Struppi.
你好 Struppi,
ich habe eine Text-Datei mit Mitgliederinformationen (feste Feldlängen).
Bei der Größe solltest du dir dringend überlegen ob du nicht auf eine
Datenbank wechseln willst.
Die reine Datenmenge macht eine Datenbank nicht sinnvoller. Da muss man sich
schon genauer anschauen, was fuer Daten das sind.
再见,
CK
Hi,
Bei der Größe solltest du dir dringend überlegen ob du nicht auf eine
Datenbank wechseln willst.Die reine Datenmenge macht eine Datenbank nicht sinnvoller. Da muss man sich
schon genauer anschauen, was fuer Daten das sind.
leider habe ich hier keine Wahl. Die Daten kommen auf CD-ROM und müssen dann als textfiles wieder auf eine Platte geschrieben werden. Mir wäre eine Datenbank auch lieber.
Sascha
Bei der Größe solltest du dir dringend überlegen ob du nicht auf eine
Datenbank wechseln willst.Die reine Datenmenge macht eine Datenbank nicht sinnvoller. Da muss man sich
schon genauer anschauen, was fuer Daten das sind.
Das war ja gar nicht die Frage, er wollte damit ja was machen:
'unnötige Felder rauslöschen' => "ALTER TABLE tabelle DROP Feld"
'Leerzeichen entfernen' => UPDATE tabellenname set spaltenname
= TRIM(spaltenname
)
Semikolon als trennzeichen => unötig
Natürlich kannst du, wenn du Fit bist evtl. ein schnelleres System schreiben als jede DB, aber ich glaub in dem Fall wären das der falsche Ratschlag.
Struppi.
你好 Struppi,
Bei der Größe solltest du dir dringend überlegen ob du nicht auf eine
Datenbank wechseln willst.Die reine Datenmenge macht eine Datenbank nicht sinnvoller. Da muss man
sich schon genauer anschauen, was fuer Daten das sind.Das war ja gar nicht die Frage, [...]
Klar ist das die Frage ;-) Du hast eine Datenbank empfohlen, obwohl du die
Umstaende nicht kennst, das war ein bisschen vorschnell. Ob eine Datenbank
sinnvoller ist, haengt von vielen Faktoren ab, u.a. vom Einsatzgebiet und
den Daten.
再见,
CK
Bei der Größe solltest du dir dringend überlegen ob du nicht auf eine
^^^^^^^^^^
Datenbank wechseln willst.
Die reine Datenmenge macht eine Datenbank nicht sinnvoller. Da muss man
sich schon genauer anschauen, was fuer Daten das sind.Das war ja gar nicht die Frage, [...]
Klar ist das die Frage ;-) Du hast eine Datenbank empfohlen, obwohl du die
^^^^^^^^^^
Umstaende nicht kennst, das war ein bisschen vorschnell. Ob eine Datenbank
sinnvoller ist, haengt von vielen Faktoren ab, u.a. vom Einsatzgebiet und
den Daten.
Eben, weil ich die Umstände nicht kenne, hab ich im geraten zu überlegen ob ... und das hat er ja anscheinend auch schon. also war mein Ratschlag nicht vorschnell, sondern entsprach genau dem was Sascha ja auch gerne wollte wenn er könnte.
Struppi.
Hallo Sascha,
little example:
open(D1,"<D1");
open(D2,">D2");
while(<D1>) {
<Zeile bearbeiten>;
print D2 "... $_ ...\n"; # Zeile wegschreiben
}
Auf diese Weise läuft nix voll, so denke ich mal, weil jede Zeile direkt weggeschrieben wird. Wenn du natürlich die Datei mit @d=<@D1>; einliest, haut es dir den Speicher voll.
Mfg,
Jonny
!!!
@d=<D1>;
!!!
_sorry_
Mfg,
Jonny