Sergej: Ausgelesene Zeilen in Perl miteinander vergleichen, WIE?

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;

richtig, oder muß @array davor??????

bei array, error: @zeile[$z_nr] better written as $zeile[$z_nr] at # xx.bat line 36.

ist der Anfangrichtig?

???????????????????????????????????????????????????????????????????

Später will ich jeweil die Zeilen-substr mit einander Vergleichen,

d.h jeder Zeilen-substr  mit jedem !! Und die Gleichen Zeilen

ausgeben.

???????????????????????????????????????????????????????????????????

Bsp:

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

  1. $/="\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

    1. Danke es geklappt!
      das habe ich gesucht: $_  !!!

      $zeile[$z_nr] = $_; # Aktuelle Zeile zwischenspeichern

      Gruß Sergej

  2. 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

    1. 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

  3. 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

    1. Moin!

      while(<>){ # Solange Zeile existiert <== ???

      Eine Zeile von was?

      STDIN, steht da doch (war aber wohl nicht gemeint) ;)

      cu
      csx

    2. Vielen Dank Philipp,

      sehr, sehr Hilfreich!

      Wahnsinn, wie schnell doch die Menschen antworten.
      Alle Antworten ins Schwarze.

      Danke sehr.

      Viele Grüße
      Sergej

    3. 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

      1. 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

  4. 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.