"Übersetzungsprobleme": PHP => PERL
Andreas
- perl
Hallo!
Ich bin dabei ein PHP-Script in ein PERL-Script zu übersetzen. An 2 Stellen habe ich aber Probleme:
1. Daten aus Dateihandle in String/Array schreiben:
open DATEN, "test.txt";
soweit so gut, mit print DATA "hallo"; kann ich ja "hallo" in die Datei schreiben, aber wie schreibe ich den Inhalt der Datei in eine Variable? Möglichst zeilenweise in einen Array(siehe 2.)!
2. Sting in einen Array zerlegen, Gegenstück zu explode("|",$daten_string) in PHP!
So sieht das ganze genau in PHP aus:
<?php
$data = fopen($file, "r");
$recordsets = fread($data,filesize($file));
fclose($data);
$data_zeilen = explode("\n",trim($recordsets));
foreach ($data_zeilen as $tmp) {
$data_array[] = explode("|", $tmp);
}
?>
Jetzt habe ich mit $data_array einen 2-Dimensionalen Array. Aber leider kennt PERL nicht dieselben Funktionen, kann mir vielleicht jemand auf die Sprünge helfen? Leider kenne ich kein vergleichbares Manual wie das von PHP!
Viel Grüße
Andreas
Huhu Andreas
soweit so gut, mit print DATA "hallo"; kann ich ja "hallo" in die Datei schreiben, aber wie schreibe ich den Inhalt der Datei in eine Variable? Möglichst zeilenweise in einen Array(siehe 2.)!
z.B. so
open(FH,"<datei.txt") || die "Fehler bei Dateizugriff";
@zeilen = <FH>;
- Sting in einen Array zerlegen, Gegenstück zu explode("|",$daten_string) in PHP!
z.B.
@arr = split('/,/',$daten_string);
Viele Grüße
lulu
Hi Lulu!
Danke Dir! Perl ist doch einfacher als man glaubt ;-)
Habe aber noch ein Problem, wie bekomme ich in PERL mehrdimensionale Arrays?
So sieht mein Versuch aus, vergleichbar funktioniert das zumindest in PHP, aber push funktioniert bei PERL anscheinend anders, es wird nicht der jeweils neue Array als Wert des Elements gespeichert, sondern der neue Array wird einfach an den ursprünglichen angehängt.
@zeilen = <DATAFILE>;
foreach(@zeilen){
push @data_array, split('/|/',$_) ;
}
Und noch eine Frage: Muß ich eigentlich den Array @data_array vorher irgendwie initialisieren? Oder kann ich das einfach so machen?
Viele Grüße
Andreas
Halihallo Andreas
Danke Dir! Perl ist doch einfacher als man glaubt ;-)
Jaja :-)
Habe aber noch ein Problem, wie bekomme ich in PERL mehrdimensionale Arrays?
@test = (['t', 't2'], ['t3', 't4']);
So sieht mein Versuch aus, vergleichbar funktioniert das zumindest in PHP, aber push funktioniert bei PERL anscheinend anders, es wird nicht der jeweils neue Array als Wert des Elements gespeichert, sondern der neue Array wird einfach an den ursprünglichen angehängt.
@zeilen = <DATAFILE>;
foreach(@zeilen){
push @data_array, split('/|/',$_) ;
}
@zeilen = <DATAFILE>;
my @data_array;
foreach (@zeilen) {
my @new_items = split /|/;
push @data_array, [@new_items];
}
Und noch eine Frage: Muß ich eigentlich den Array @data_array vorher irgendwie initialisieren? Oder kann ich das einfach so machen?
wenn du mit use strict arbeitest, musst du es vorher initialisieren. Aber du meinst wohl, dass es nur "Arrays" aufnimmt. Nein, dafür musst du einfach eine Referenz in @data_array pushen. Die Referenz legst du an, indem du [@new_items] schreibst. Das gibt dann eine Pointer/Referenz auf einen anonymes Array. So werden Multidimensionale Datenstrukturen angelegt.
Viele Grüsse
Philipp
Halihallo Andreas
@zeilen = <DATAFILE>;
my @data_array;
foreach (@zeilen) {
my @new_items = split /|/;
push @data_array, [@new_items];
}
Übrigens: Das auslesen von werten ist dann anders, als in php (glaub ich):
$data_array[1]->[15]
desweiteren kannst du auch
$pointer = @new_items
schreiben, aber Achtung: in einigen Fällen wird das Array dann vom Garbage Collector (Speicheraufräumer) gefressen und der Pointer zeigt ins Nirvana. Also lieber obige Lösung nehmen, ist sicherer. Gut, bei "einfacher" Programmierung dürfte wohl auch letzteres funktionieren, aber bei komplexen Verschachtelungen und Wiederverwendung der Referenz wird der "InGebrauchIndex" nicht aktualisiert, das führt dazu, dass er schneller 0 ist, als er eigenlich sollte => wird früher vom GC gefressen als gewollt.
Viele Grüsse
Philipp
Hallo!
Danke Dir! Alsodoch etwas anders aberrnicht unbedingt schlechter! Nur Leider fehlt das Kapitel in meinem PERL-Buch.
Aber ich war ja auch nicht untätig, ich habe mir überlegt das ein Mehrdimensionaler Array ja evtl gar nicht benötigt wird! ich habe das jetzt direrekt anstatt in der Schleife den Array zu erzeugen in die Excel_Datei geschreiben, aber funktioniert hat das nicht richtig, der inhalt der .txt wurde Zeilenweise in die Excel-Datei geschreiben. Kann es sein das es was damit zu tun hat das ich $_ 2 mal verwende? Geht das dann nur mit einer for Schleife?
der inhalt der txt:
A1|B1
A2|B2
@zeilen = <DATAFILE>;
my $row = 0;
foreach(@zeilen){
@tmp_data = split /|/, $_;
my $col = 0;
foreach(@tmp_data){
$worksheet->write($row, $col, $_);
$col++;
}
$row++;
}
Grüße
Andreas
Hallo!
A1|B1
A2|B2
Also jetzt bin ich wieder etwas weiter, hat wohl was mit $_ zu tun gehabt, jedenfalls habe ich jetzt nich das Problem, das nicht bei dem Zeichen | getrennt wird, sondern nach jedem Zeichen?! Also ich bekomme iene Excel-Tabelle die so aussieht:
+-----+-----+-----+-----+-----+
| A | 1 | | | B | 1 |
+-----+-----+-----+-----+-----+
| A | 2 | | | B | 2 |
+-----+-----+-----+-----+-----+
So sieht der Code dazu aus:
@zeilen = <DATAFILE>;
my $row = 0;
foreach $zeile (@zeilen) {
my @tmp_data = split /|/, $zeile;
my $col = 0;
foreach $item (@tmp_data){
$worksheet->write($row, $col, $item);
$col++;
}
$row++;
}
Ich weiß auch nicht, aber eigentlich sollte das doch so funktionieren, oder?
Viele Grüße
Andreas
Halihallo Andreas
A1|B1
A2|B2
Also jetzt bin ich wieder etwas weiter, hat wohl was mit $_ zu tun gehabt, jedenfalls habe ich jetzt nich das Problem, das nicht bei dem Zeichen | getrennt wird, sondern nach jedem Zeichen?! Also ich bekomme iene Excel-Tabelle die so aussieht:
Pfui, Andreas! :-) - '|' ist reserviert und bedeutet oder. Eine Regexp mit _nur_ oder heisst: Jeder Buchstabe splitten...
Also: Escapen, dann funktionierts: | statt |.
my @tmp_data = split /|/, $zeile;
=> my @tmp_data = split /|/, $zeile;
Viele Grüsse
Philipp
Hi Philipp!
Pfui, Andreas! :-) - '|' ist reserviert und bedeutet oder. Eine Regexp mit _nur_ oder heisst: Jeder Buchstabe splitten...
Also: Escapen, dann funktionierts: | statt |.
Ah ja, da war mal was ;-)
my @tmp_data = split /|/, $zeile;
=> my @tmp_data = split /|/, $zeile;
Das klappt prima! Danke Dir! Das ganze Teil funktioniert jetzt fürs erste! und ich fange tatsächlich an PERL zu mögen, wobei ich immer noch große Probleme habe, denn viele Sachen die ich in PHP "mal eben" mache weiß ich nicht wie es in PERL funktioniert, aber am Ende geht es da meist noch einfacher! Naja, aber ich brauche jetzt doch die Array Version, denn ich muß den höchsten/niedrigsten Preis pro "Zeile" errechnen, mal gucken wie ich das mache ;-)
Grüße
Andreas
Halihallo Andreas
my @tmp_data = split /|/, $zeile;
=> my @tmp_data = split /|/, $zeile;
Das klappt prima! Danke Dir! Das ganze Teil funktioniert jetzt fürs erste! und ich fange tatsächlich an PERL zu mögen
Juhuiii! Einer mehr im Boot ;-)
wobei ich immer noch große Probleme habe, denn viele Sachen die ich in PHP "mal eben" mache weiß ich nicht wie es in PERL funktioniert, aber am Ende geht es da meist noch einfacher!
Na, was meinst du wohl wie es mir geht, wenn ich php programmiere? - Genau so!.
Naja, aber ich brauche jetzt doch die Array Version, denn ich muß den höchsten/niedrigsten Preis pro "Zeile" errechnen, mal gucken wie ich das mache ;-)
my @preise = qw(50 100 150 75 30 80 300 225);
my @sorted = sort {$a<=>$b} @preise;
my $minimal = shift @sorted;
my $maximal = pop @sorted;
print 'Minimal: ' . $minimal . "\n" . 'Maximal: ' . $maximal;
:-)
Viele Grüsse
Philipp
Halihallo Andreas
my @tmp_data = split /|/, $zeile;
=> my @tmp_data = split /|/, $zeile;
Das klappt prima! Danke Dir! Das ganze Teil funktioniert jetzt fürs erste! und ich fange tatsächlich an PERL zu mögen
Juhuiii! Einer mehr im Boot ;-)
wobei ich immer noch große Probleme habe, denn viele Sachen die ich in PHP "mal eben" mache weiß ich nicht wie es in PERL funktioniert, aber am Ende geht es da meist noch einfacher!
Na, was meinst du wohl wie es mir geht, wenn ich php programmiere? - Genau so!.
Naja, aber ich brauche jetzt doch die Array Version, denn ich muß den höchsten/niedrigsten Preis pro "Zeile" errechnen, mal gucken wie ich das mache ;-)
my @preise = qw(50 100 150 75 30 80 300 225);
my @sorted = sort {$a<=>$b} @preise;
my $minimal = shift @sorted;
my $maximal = pop @sorted;
print 'Minimal: ' . $minimal . "\n" . 'Maximal: ' . $maximal;
:-)
Viele Grüsse
Philipp
Halihallo Andreas
[...] - Öm... Seit wann bist du so wortkarg???
Oder hat dir ein \012\015 dazwischengefunkt???
;)
Viele Grüsse
Philipp
Ups, war ein Versehen ;-)
Hi Philipp!
Juhuiii! Einer mehr im Boot ;-)
jajaja, aber noch kann ich auf mein PHP nicht verzichten, denn wie gesagt, in PERL bekomme ich einige Sachen nicht so ohne weiteres hin!
Na, was meinst du wohl wie es mir geht, wenn ich php programmiere? - Genau so!.
Das geht nicht, es können ja nicht beide Sprachen einfacher sein als die andere ;-)
Das hatte ich gar nicht so gemeint ;-) Aber wenn wir schonmal dabei sind:
my @preise = qw(50 100 150 75 30 80 300 225);
my @sorted = sort {$a<=>$b} @preise;
Was ist $a und $b? Wofür brauchst Du das? Was hat $a und $b für einen Wert?
Und noch ein Problem, wenn ichg denn jetzt einen "Mehrdimensionalen Array" habe, bekomme ich dann z.B. den ersten eindimensionalen Array über @tmp_array = @preise[1]?
also
$i=0;
foreach(@preise){
my @tmp_array = @preise[$i]
my @sorted = sort {$a<=>$b} @tmp_array;
my $minimal = shift @sorted;
my $maximal = pop @sorted;
$i++;
}
So in etwa?
macht zwar so wenig Sinn, aber ich will ja auch direkt in der Schleife die Daten dann in mein Excel-heet schreibn und die niedrigsten anders formatieren! Geht erstmal nur ums Prinzip!
Danke nochmal!
Viele Grüße
Andreas
Halihallo Andreas
Ups, war ein Versehen ;-)
:-)
Juhuiii! Einer mehr im Boot ;-)
jajaja, aber noch kann ich auf mein PHP nicht verzichten, denn wie gesagt, in PERL bekomme ich einige Sachen nicht so ohne weiteres hin!
wird noch! ;)
my @preise = qw(50 100 150 75 30 80 300 225);
my @sorted = sort {$a<=>$b} @preise;
Was ist $a und $b? Wofür brauchst Du das? Was hat $a und $b für einen Wert?
$a und $b sind globale Variablen, die von sort benutzt werden. Du kannst durch die "subroutine" in {...} spezifizieren, _wie_ sortiert werden soll. $a und $b sind hierbei die einzelnen Elemente, die verglichen werden. Also
1 3 5 7 5 2
sort { $a <=> $b }
=> 1 <=> 3 = 1 => kleiner
=> 3 <=> 5 = 1 => kleiner
=> 5 <=> 7 = 1 => kleiner
...
=> 5 <=> 2 = 0 => grösser => umdrehen
=> 1 2 3 5 5 7
naja, ist wahrscheinlich etwas schneller implementiert...
so kannst du z. B. {uc($a) cmp uc($b)} verwenden, um Strings caseinsensitiv zu sortieren...
perldoc -f sort !
Und noch ein Problem, wenn ichg denn jetzt einen "Mehrdimensionalen Array" habe, bekomme ich dann z.B. den ersten eindimensionalen Array über @tmp_array = @preise[1]?
Ne, wie Christian schon sagte, sind Arrays wirklich nur Listen mit einzelnen Werten. D. h. es gibt nur ein $preise[1], aber kein @(Array). Aber, du hast ja in $preise[1] eine Referenz auf ein Array und das kannst du dann "benutzen":
my $ptr = $preise[1]; # Pointer auf das Array
my @tmp = @{$ptr}; # Abbild des anonymen Arrays machen
# Achtung: Array in Adresse $ptr wird
# _nicht_ verändert.
oder
$ptr->[1] = 'Hasi'; # jetzt wird der index 1 des _anonymen_
# Arrays durch 'Hasi' ersetzt.
$i=0;
foreach(@preise){
my @tmp_array = @preise[$i]
my @sorted = sort {$a<=>$b} @tmp_array;
my $minimal = shift @sorted;
my $maximal = pop @sorted;
$i++;
}
s. oben:
my @tmp_array = @{$preise[$i]}
Viele Grüsse
Philipp
Hallo!
@zeilen = <DATAFILE>;
my @data_array;
foreach (@zeilen) {
my @new_items = split /|/;
brauche ich denn hier kein $_ ?
push @data_array, [@new_items];
}
Grüße
Andreas
Halihallo Andreas
@zeilen = <DATAFILE>;
my @data_array;
foreach (@zeilen) {
my @new_items = split /|/;
brauche ich denn hier kein $_ ?
Es gibt viele Funktionen in Perl, die, wenn kein Parameter explizit angegeben ist, den "Standardwert" $_ nehmen. Unter anderem gehört split zu diesen Funktionen, schau mal perldoc -f split an, da wirst du darauf hingewiesen werden.
Viele Grüsse
Philipp
Hallo,
Danke Dir! Perl ist doch einfacher als man glaubt ;-)
Na siehste;-)
Habe aber noch ein Problem, wie bekomme ich in PERL mehrdimensionale Arrays?
Lies Dir einmal http://www.perldoc.com/perl5.6/pod/perllol.html durch.
Und für alle möglichen Datenstrukturen gibts dann noch http://www.perldoc.com/perl5.6/pod/perldsc.html.
@zeilen = <DATAFILE>;
foreach(@zeilen){
push @data_array, split('/|/',$_) ;
Mit ein paar Klammern wird das noch etwas:
push @data_array, [split('/|/',$_)] ;
}
Und noch eine Frage: Muß ich eigentlich den Array @data_array vorher irgendwie initialisieren? Oder kann ich das einfach so machen?
Grundsätzlich solltest Du im Script
use strict;
verwenden.
dann wird das Array (oder andere Variablen) mit (beispielsweise)
my(@data_array,$wert);
eingeführt.
Willst Du es leeren, so kannst Du eine leere Liste zuweisen:
@data_array = ();
Das brauchst UD aber nicht, wnen Du das Array das erste Mal verwendest, es schadet aber auch nicht, und kann ev. iregndwann eine Menge Kopfweh vermeiden, da psuh, ja nur n das bestehende Array anhängt.
Grüße
Klaus
Hallo,
Habe aber noch ein Problem, wie bekomme ich in PERL mehrdimensionale Arrays?
In Perl gibt es in dem Sinne keine mehrdimensionalen Arrays. Perl verwaltet
Arrays als lineare Listen. Mit anderen Worten, wenn du
$array[1] = @narr;
schreibst, wird @narr hinter $array[1] in den Array eingehaengt. Du musst dich
mit Referenzen behelfen, wie meine beiden Vorredner schon beschrieben haben.
Gruesse,
CK