Ausgelesene Zeilen in Perl miteinander vergleichen, WIE?
Sergej
- perl
Hallo liebe Leser,
habe folgendes Problem:
mittels
open(FHin, "< $inFile") or die "\nKann $inFile nicht oeffnen: $!";
lese ich den Testfile ein, kein Problem.
mittels
open(FHout,">> $outFile" ) or die "\nKann $outFile nicht zum Anhängen oeffnen: $!";
zum schreiben öffnen, auch kein Problem.
--------------UND jetzt! ---------------
$/="\n"; # Ende einer Zeichenkette ist der Zeilenumbruch !!
my $z_nr = 0;
while(<>){ # Solange Zeile existiert <== ???
$z_nr++;
@zeile[$z_nr] = chomp;
???????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????
my $MsgVon = 23;
my $MsgBis = 45;
@Msg[$z_nr] = substr($zeile[$z_nr], $MsgVon, $MsgBis);
for($wert=$z_nr; $wert>=1; $wert--){
if ($Msg[$z_nr] == $Msg[$wert] {
print FHout "$zeile[$z_nr]\n"; print FHout "$zeile[$wert]\n";
}
}
-----------------------------------------------------
Danke für die Hilfe!
Gruß Sergej
$/="\n"; # Ende einer Zeichenkette ist der Zeilenumbruch !!
Das ist standardmäßig gesetzt. Kann aber nicht schaden, es nochmal zu setzen
while(<>){ # Solange Zeile existiert <== ???
Das würde STDIN einlesen. Du meinst wahrscheinlich while(<FHin>)
@zeile[$z_nr] = chomp;
Das geht nicht. Du willst wahrscheinlich die newslines der aktuellen Zeile entfernen, oder? Einfach chomp; reich aus. Die aktuelle Zeile findest du in $_
bei array, error: @zeile[$z_nr] better written as $zeile[$z_nr] at # xx.bat line 36.
Ja, denn die einzelnen Elemente eines Arrays (zB @meinarray) werden über scalare angesprochen ($meinarray[1], $meinarray[2], ..., $meinarray[-1])
ist der Anfangrichtig?
Öhmm ;)
csx
Danke es geklappt!
das habe ich gesucht: $_ !!!
$zeile[$z_nr] = $_; # Aktuelle Zeile zwischenspeichern
Gruß Sergej
Hallo Sergej,
die Antworten auf Deine Fragen gibt es alle hier:
http://www.perldoc.com/perl5.8.0/pod/perlfaq4.html
What is the difference between $array[1] and @array[1]?
How do I compute the difference of two arrays? How do I compute the intersection of two arrays?
Fehlermeldungen etc. nicht in den Code schreiben,
lieber den ganzen Code und dann mit Zeilennummern.
Finde ich übersichtlicher.
Viele Grüße
annA
Hi!
die Antworten auf Deine Fragen gibt es alle hier:
http://www.perldoc.com/perl5.8.0/pod/perlfaq4.html
oder auch hier: www.google.com
SCNR
gruß
csx
Halihallo Sergej
habe folgendes Problem:
mittels
open(FHin, "< $inFile") or die "\nKann $inFile nicht oeffnen: $!";
lese ich den Testfile ein, kein Problem.
Dateihandles sollten GROSS geschrieben. Kleine Stilkritik.
$/="\n"; # Ende einer Zeichenkette ist der Zeilenumbruch !!
brauchst du nicht.
while(<>){ # Solange Zeile existiert <== ???
Eine Zeile von was? - Verwende besser den Dateihandle:
while( <FHin> )... und ja, solange noch Zeilen einzulsesen sind, tue dis, tue das...
@zeile[$z_nr] = chomp;
Dann enthält @zeile[$z_nr] immer das gelöschte Zeichen, sprich die Newline.
chomp;
$zeile[$z_nr] = $_;
Ein Element eines Arrays ist und bleibt ein Skalar => $ statt @. Mit @zeile[...] erhälst
du einen splice (Teilbereich) des Arrays, das willst du hier aber nicht.
perldoc perldata
richtig, oder muß @array davor??????
@array davor? - Was meinst du damit. Dennoch ein nein vorab.
bei array, error: @zeile[$z_nr] better written as $zeile[$z_nr] at # xx.bat line 36.
Tja, ein Splice über einen Index ist das Element per se, aber auf die Elemente eines
Arrays sollte besser mit
$array[$index]
zugegriffen werden.
my $MsgVon = 23;
my $MsgBis = 45;
@Msg[$z_nr] = substr($zeile[$z_nr], $MsgVon, $MsgBis);
$Msg[$z_nr]...
for($wert=$z_nr; $wert>=1; $wert--){
if ($Msg[$z_nr] == $Msg[$wert] {
^^
eq statt ==, denn == ist für den Vergleich zweier Zahlen. eq ist das Äquivalent für
Strings.
Wenn du jede Zeile mit jeder vergleichen willst, wirst du zwei for-Schleifen benötigen.
for ( my $i=0; $i < @Msg; $i++ ) {
for ( my $j=0; $j < @Msg; $j++ ) {
next if ( $i == $j ); # sonst wird jeder Eintrag ausgegeben, da jeder mit sich
# selber verglichen true ist.
if ($Msg[$i] eq $Msg[$j]) {
print FHout $Msg[$i]."\n";
}
}
}
Viele Grüsse
Philipp
Moin!
while(<>){ # Solange Zeile existiert <== ???
Eine Zeile von was?
STDIN, steht da doch (war aber wohl nicht gemeint) ;)
cu
csx
Vielen Dank Philipp,
sehr, sehr Hilfreich!
Wahnsinn, wie schnell doch die Menschen antworten.
Alle Antworten ins Schwarze.
Danke sehr.
Viele Grüße
Sergej
Hallo Philipp,
Die Schleife ist gut, nur das die gleichen Zeilenpaare mehrmals(>10 mal) im FHout auftauchen.
PS: Die Zeilen sind im FHin einmalig!! nur die Msg kann gleich sein!
Wie löse ich jetzt das Problem?
_____________________________________________________
for ( my $i=0; $i < @Msg; $i++ ) {
for ( my $j=0; $j < @Msg; $j++ ) {
next if ( $i == $j ); # sonst wird jeder Eintrag ausgegeben, da jeder mit sich
# selber verglichen true ist.
if ($Msg[$i] eq $Msg[$j]) {
print FHout $Zeile[$i]; # Brauche Zeile, da sie mehr Infos enthält, Msg dient nur zum Vergleich!
print FHout $Zeile[$j]."\n"; # Mit 2xprint bilde ich Paare, die Verglichen werden!
}
}
}
-------------------------------------------------------
Danke, Gruß Sergej
Halihallo Sergej
Die Schleife ist gut, nur das die gleichen Zeilenpaare mehrmals(>10 mal) im FHout auftauchen.
Ja, ich habe einen klassischen Fehler begangen, sorry.
---
Also, du hast ein Array @Msg und möchtest die darin mehrmals vorkommenden Einträge
ausgeben? - Also alls Messages stehen in @Msg und du möchtest die doppelt oder mehrfach
vorkommenden ausgeben lassen. Richtig?
Dann ist dies wohl sinnvoller:
my %similar_count = ();
for ( my $i=0; $i < @Msg; $i++ ) {
$similar_count{$Msg[$i]}++; # jede gleiche Zeile erhöht den Wert um 1.
if ($similar_count{$Msg[$i]} == 2) { # wenns dreimal vorkommt, is schon ausgegeben.
print FHout $Zeile[$i];
}
}
Viele Grüsse
Philipp
Hallo liebe Leser,
habe folgendes Problem:
mittels
open(FHin, "< $inFile") or die "\nKann $inFile nicht oeffnen: $!";
open(FHout,">> $outFile" ) or die "\nKann $outFile nicht zum Anhängen oeffnen: $!";
$/="\n"; # Ende einer Zeichenkette ist der Zeilenumbruch !!
Das ist nicht nötig.
my $z_nr = 0;
Eigentlich auch nicht. Du kannst mit einem push @Array, $wert ein array erweitern.
while(<>){ # Solange Zeile existiert <== ???
while(<FHin>){
$z_nr++;
@zeile[$z_nr] = chomp;richtig, oder muß @array davor??????
bei array, error: @zeile[$z_nr] better written as $zeile[$z_nr] at # xx.bat line 36.
Da steht doch schon, was du machen sollst.
Jetzt ist die Frage, ob du wirklich die Datei in ein Array einlesen willst, oder hier on the fly die Datei vergleichen.
Im ersten Falle würde das obige zu einem:
chomp(my @zeile = <FHin>);
Das reicht dann auch.
Im zweiten Falle frage ich mich wozu du das Array brauchst, da es gegebenenfalls sehr grossw erden kann.
Daher würde reichen:
my $zeile = chomp(<FHin>);
my $MsgVon = 23;
my $MsgBis = 45;
@Msg[$z_nr] = substr($zeile[$z_nr], $MsgVon, $MsgBis);
Warum schon wieder ein Array?
Du verwendest nur einen Skalar und kannst dann mit index() die einzelnen Buchstaben benutzen.
for($wert=$z_nr; $wert>=1; $wert--){
Das geht perliger:
for my $wert($z_nr..1)
if ($Msg[$z_nr] == $Msg[$wert] {
print FHout "$zeile[$z_nr]\n"; print FHout "$zeile[$wert]\n";
}
}
Hier erschliesst sich mit nicht der Sinn.
Du vergleichst einen Ausschnitt der Orginal zeile mit einem undefinierten Wert.
arbeitest du nicht mit use strict?
Du soltest unbedingt diese zwei Zeilen am anfang in deinem Programm einbauen und versuchen die Fehlermeldungen zu entfernen:
#!/usr/bin/perl -w
use strict;
Außerdem solltest du dir dringend nochmal die Dokumentationen zu den von dir verwendeten Funktinen durchlesen. es macht mir den Eindruck, dass du gar nicht weisst was diese machen.
Struppi.