Dateibearbeitung (Newbie)
bibo
- perl
Hallo, ich programmiere noch nicht sehr lange perl, und jetzt hab ich ein problem bei dem ich nicht weiterkomme. ich hoffe irgendeiner von euch kann mir evtl. helfen.
ich muss eine textdatei einlesen, die als tabelle aufgebaut ist.daraus muss ich einige daten abfragen und dann diese datensätze wieder in eine textdatei ausgeben, die ebenfalls als tabelle aufgebaut ist.
also feldname1,fledname2...
wert1.1,wert1.2...
wert2.1,wert2.2...
das problem ist eigentlich nicht das einlesen, sonder das es so viele feldnamen sind, das es über 4 zeilen geht.
ich habe schon ein gutes script im forum gefunden, nur liest man da für die feldnamen nur die erste zeile ein, wie kann ich das umstellen so das ich die ersten 4 zeilen als feldnamen einlese?
hir mal das script.
und vielen dank im voraus.
#!/usr/bin/perl
@Adressen = (""); # Speicher für alle Datensaetze
@Datensatz = (""); # Speicher für alle Felder des aktuellen Datensatzes
$Felder = ""; # Speicher für die Namen der Felder (stehen in der ersten Dateizeile
$i = 0;
open(eingabe, "<eingabedatei.txt") || die "Adressendatei nicht gefunden\n";
while(<eingabe>) # Kommabegrenzte Datei einlesen
{
if($i == 0) # erste Zeile der Datei einlesen
{
$Felder = $_; # Feldnamen ermitteln
}
else
{
$Adressen[$i] = $_; # ab zweiter Zeile in @Adressen einlesen
}
$i++; # Datensatzzähler erhöhen
}
close(eingabe);
$Anzahl = $i - 1; # Anzahl Datensätze merken
chop($Felder);
@Datenfelder = split(/,/,$Felder); # Erste Zeile mit Feldnamen aufdröseln
open(OUT, ">ausgabe.txt"); # HTML-Datei zum Schreiben öffnen
for(@Adressen) # solange Daten in der Adressenliste sind
{
@Datensatz = split(/,/,$_); # Aktuellen Datensatz aufdröseln
$i = 0;
for(@Datensatz)
{
print OUT "$Datenfelder[$i]"; # Aktuellen Datensatz schreiben
print OUT "\n";
print OUT "$Datensatz[$i]"; # Aktuellen Datensatz schreiben
$i++;
}
}
#print OUT $Felder;
close(OUT);
print $Anzahl," Datensaetze geschrieben\n"; # Nur zur Kontrolle: auf Standardausgabe
Hi,
ich muss eine textdatei einlesen, die als tabelle aufgebaut ist.
das Format nennt sich CSV, Comma Separated Values (auch wenn es keine Kommas sind, sondern z.B. Tabulatoren).
das problem ist eigentlich nicht das einlesen, sonder das es so viele feldnamen sind, das es über 4 zeilen geht.
Da das Filesystem, mit dem Du arbeitest, nichts vom Konzept "Zeilen" weiß, kann es auch keine Beschränkung für die Länge geben. Speichere also alle Werte eines Datensatzes in _eine_ Zeile.
ich habe schon ein gutes script im forum gefunden, nur liest man da für die feldnamen nur die erste zeile ein, wie kann ich das umstellen so das ich die ersten 4 zeilen als feldnamen einlese?
Indem Du den Lesevorgang vier- statt nur einmal machst. Ich möchte Dir aber davon abraten: Das aktuelle Dateiformat ist suboptimal.
#!/usr/bin/perl
#!/usr/bin/perl -w
use strict;
Anschließend werden Dir viele Fehler genannt werden, die Du korrigieren solltest. Lies hierzu auch
perldoc -f my
@Adressen
perldoc perlstyle (Großschrift in Variablennamen)
= (""); # Speicher für alle Datensaetze
Du füllst das Array hier mit einem leeren Wert, möchtest aber - vermutlich! - _keinen_ Wert haben. Lass die Quotes weg.
Gewöhn Dir bitte außerdem an, nur dann "Doublequotes" zu verwenden, wenn Du sie _wirklich_ brauchst. Ansonsten wähle 'Singlequotes'.
open(eingabe, "<eingabedatei.txt") || die "Adressendatei nicht gefunden\n";
In den Sterbeschrei solltest Du noch $! einbauen, damit Du den Grund erkennst. Hier ist außerdem so ein Fall, wo Singlequotes angebracht werden; und im Gegensatz zu Variablennamen sollten Handler durchgehend groß geschrieben werden.
while(<eingabe>) # Kommabegrenzte Datei einlesen
Hier wird nicht die Datei, sondern eine Zeile derselben eingelesen => möglicher Ansatzpunkt
{
if($i == 0) # erste Zeile der Datei einlesen
Auch die Klammernsetzung (sowohl geschweifte als auch runde - im Gegensatz zu open() ist if keine Funktion) solltest Du in perldoc perlstyle nachlesen.
$Felder = $_; # Feldnamen ermitteln
Wenn die Datei einzeilige Datensätze enthält, kannst Du dies ohne if-Prüfung vor der while-Schleife machen. Außerdem empfehle ich perldoc perlvar, speziell "$.".
$Adressen[$i] = $_; # ab zweiter Zeile in @Adressen einlesen
Schön - viele begehen den Fehler, hier @array[$index] mit "@" zu sagen :-)
$i++; # Datensatzzähler erhöhen
$Anzahl = $i - 1; # Anzahl Datensätze merken
Was mit "+" geht, geht auch mit "-".
chop($Felder);
Veraltet. Siehe perldoc -f chomp
open(OUT, ">ausgabe.txt"); # HTML-Datei zum Schreiben öffnen
Singlequotes mal wieder; außerdem sollte hier unbedingt auch ein "or die" hin.
@Datensatz = split(/,/,$_); # Aktuellen Datensatz aufdröseln
Nebenbei: $_ ist hier implizit.
print OUT "$Datenfelder[$i]"; # Aktuellen Datensatz schreiben
perldoc perlfaq4
What's wrong with always quoting "$vars"?
print OUT "\n";
print OUT "$Datensatz[$i]"; # Aktuellen Datensatz schreiben
Die drei Zeilen gehen übrigens auch in eine.
$i++;
Warum minnst Du eigentlich gleich eine "for (my $i=0; ...)"-Schleife?
close(OUT);
Bei Schreibzugriffen solltest Du auch beim abschließenden close() unbedingt Fehler abfangen.
Cheatah
Hallo bibo,
Cheata hat Dir ja schon ausführlich geantwortet. Nur noch angemerkt: das CPAN http://cpan.perl.com ist eine große (und imvho geniale) Sammlung von Perlmodulen. Denn: das Rad wurde bereits erfunden .. und Du bist nicht der erste, der kommaseperierte Listen bearbeiten möchte.
Du solltest mal einen Blick werfen auf:
http://www.perldoc.com/perl5.6.1/lib/Text/CSV.html
und
http://www.perldoc.com/perl5.6.1/lib/Text/CSV_XS.html
Grüße
K@rl
PS:
ich muss eine textdatei einlesen, die als tabelle aufgebaut ist.
ist das eine Übungs-/Prüfungsaufgabe?
vielen dank für eure hilfe, ich werd das gleich mal ausprobieren.
jepp, das ist eine übungsaufgabe, muss nämlich gerade auf die abschlußprüfung als applikationsentwickler lernen.
also wie gesagt vielen dank.
Hi,
jepp, das ist eine übungsaufgabe,
schreibe einen Converter, der aus dem vierzeiligen Schmonsens ordentliches CSV macht... ;-)
Cheatah
P.S.: Nein, das war nicht so scherzhaft gedacht, wie der Smiley vermuten lässt.
Hallo Cheatah,
... nur um ggfs. den Ruf zu untermauern, ich sei ein wenig arrogant ... aber ... wenn das das Niveau einer *Abschluß*prüfung ist ... dann schüttel' ich schon mit dem Kopf ...
K@rl
Hi,
... nur um ggfs. den Ruf zu untermauern, ich sei ein wenig arrogant ...
sind wir das (zumindest mit dem Ruf belegt) nicht alle? ;-)
aber ... wenn das das Niveau einer *Abschluß*prüfung ist ... dann schüttel' ich schon mit dem Kopf ...
Nun ja... im Prinzip hast Du ja recht, aber die Betrachtung finde ich doch etwas einseitig. Es ist schon eine Prüfung, jemanden mit einer Technik zu konfrontieren, die er noch nicht beherrscht. Da kann ein im Prinzip triviales Problem schon mal deutlich umfangreicher erscheinen, als es eigentlich ist.
Als angehender "Applikationsentwickler" (mal wieder 'ne tolle Vermeidung[1] des Wortes "Programmierer" *g*) sollte man jedoch in der Lage sein, ein Problem zunächst einmal unabhängig von der verwendeten Technik zu analysieren, mit dem Ziel einen Algorithmus bzw. ein Konzept zu entwickeln ("PAP" ist ein Begriff?). Dies dann in Perl, PHP, Java oder japanisch runterzuskribbeln ist letztlich eine Frage des Wörterbuchs - sprich: der Dokumentation. Das schwierigste ist halt die Grammatik. Die Qualität des Codes würde ich mit der sauberen Aussprache vergleichen :-)
Cheatah
[1] Ich bin offiziell "Software-Entwickler"... :-)