Lars: Fehler in Prozedur oder Hile ich bin blind

hi,

folgendes prob: ich schreibe mit einem script html-code in eine bestehene html-seite, nun moechte ich aber (wenn sich der html-code aendert) diesen auch wieder aus dieser datei rauskriegen.
mein ansatz: ich schreibe in die html-datei <!--SCRIPTSTART--> mein html-code <!--SCRIPTENDE-->.
nun moechte ich den text zwischen diesen beiden zeilen "killen" und statt der beiden <!-- --> nur <!--SCRIPTSTART--> da stehen haben, als anfangsmarke fuer das reinschreibscript. (die rechtschreibung ist ok!)

hier meine sub dafuer, wenn ich sie ausfuehre, loescht er mir ja auch den alten eintrag er schreibt auch <!--SCRIPTSTART--> hin, aber dann nicht den Rest der html-datei. d.h. <!--SCRIPTSTART--> steht dann am ende der html-datei und nicht wie gewollt mitten in der datei.

koennte sich jemand bitte dieses problems antun?

sub check4old_script{
$errormsg="Fehler beim Laden der Datei: $meine_html (";
open (DATEI $meine_html) &error($errormsg.$!.')');
@lines=<DATEI>;
close (DATEI);
$filesize=@lines;
$errormsg="Fehler beim Durchchecken nach altem Code in der Datei: $meine_html (";
open (DATEI>$meine_html) &error($errormsg.$!.')');
for ($f=0;$f<=$filesize;$f++) {
  $_=$lines[$f];
  if (/<!--SCRIPTSTART-->/) {
    while ($_ ne /<!--SCRIPTENDE-->/) {
     $_=$lines[$f];
     $f++;
    }
   print DATEI '<!--SCRIPTSTART-->';
  }
else {print DATEI $_;}
$f++;
}
close (DATEI);
}

vielen dank schon mal soweit

bye lars

  1. Hallo Lars,

    hi,

    folgendes prob: ich schreibe mit einem script html-code in eine bestehene html-seite, nun moechte ich aber (wenn sich der html-code aendert) diesen auch wieder aus dieser datei rauskriegen.
    mein ansatz: ich schreibe in die html-datei <!--SCRIPTSTART--> mein html-code <!--SCRIPTENDE-->.
    nun moechte ich den text zwischen diesen beiden zeilen "killen" und statt der beiden <!-- --> nur <!--SCRIPTSTART--> da stehen haben, als anfangsmarke fuer das reinschreibscript. (die rechtschreibung ist ok!)

    hier meine sub dafuer, wenn ich sie ausfuehre, loescht er mir ja auch den alten eintrag er schreibt auch <!--SCRIPTSTART--> hin, aber dann nicht den Rest der html-datei. d.h. <!--SCRIPTSTART--> steht dann am ende der html-datei und nicht wie gewollt mitten in der datei.

    koennte sich jemand bitte dieses problems antun?

    antun ist, glaube ich, der richtige Ausdruck ; )

    #!perl

    Du solltest *immer*

    use strict;

    und dann natuerlich my verwenden (lass ich *hier* der Einfachheithalber weg)

    sub check4old_script{
    $errormsg="Fehler beim Laden der Datei: $meine_html (";
    open (DATEI $meine_html) &error($errormsg.$!.')');

    hier fehlt ein ','.
    open DATEI, $meine_html or die "open DATEI: $!";

    @lines=<DATEI>;
    close (DATEI);
    $filesize=@lines;

    kannst Du weglassen und $#lines benutzen

    $errormsg="Fehler beim Durchchecken nach altem Code in der Datei: $meine_html (";
    open (DATEI>$meine_html) &error($errormsg.$!.')');

    open DATEI, ">$meine_html" or die "open DATEI: $!";

    for ($f=0;$f<=$filesize;$f++) {

    for ($f=0; $f=$#lines;$f++) {
    oder gar
    for (0.. $#lines) {

    $_=$lines[$f];
      if (/<!--SCRIPTSTART-->/) {
        while ($_ ne /<!--SCRIPTENDE-->/) {

    Du meinst (wahrscheinlich)
    while ($_ ne '<!--SCRIPTENDE-->') {

    $_=$lines[$f];
         $f++;
        }
       print DATEI '<!--SCRIPTSTART-->';
      }

    »»  else {print DATEI $_;}
    »»  $f++;

    Hier erhoehst Du den Index ein zweitesmal, d.h. Du ueberspringst jedesmal eine Zeile.

    }
    close (DATEI);
    }

    Kann sein, dass ich noch etwas uebersehen habe, den Code solltest Du aber auf jeden Fall noch mal ueberdenken.

    Ich wuerde es so machen:

    #!perl -w

    use strict;

    my $meine_html = 'test.html';
    my $neue_html  = 'test_neu.html';

    open DAT, $meine_html or die "open $meine_html: $!";
    open NEU, ">$neue_html" or die "open $neue_html: $!";

    while (<DAT>) {
    print NEU;
    last if /<!--SCRIPTSTART-->/;
    }

    while (<DAT>) { last if /<!--SCRIPTENDE-->/ }

    while (<DAT>) { print NEU};

    close DAT;
    close NEU;

    rename ($neue_html, $meine_html); # bei Bedarf

    vielen dank schon mal soweit

    bye lars

    Gruss
       Kai

    1. Hi,

      #!perl

      Du solltest *immer*

      use strict;

      ...und den w-Switch...

      und dann natuerlich my verwenden (lass ich *hier* der Einfachheithalber weg)

      Also:

      #!/path/to/perl -w
      use strict;

      ;-)

      $filesize=@lines;

      kannst Du weglassen und $#lines benutzen

      Nope. scalar @lines liefert die Zahl der Elemente, $#lines den Index des letzten Elementes. Wenn nun beispielsweise $[ auf einen Wert ungleich 0 gesetzt ist, liefert $#lines überhaupt nicht mehr, was man möchte.

      open (DATEI>$meine_html) &error($errormsg.$!.')');

      open DATEI, ">$meine_html" or die "open DATEI: $!";

      Es ist im Prinzip schon okay, eine eigene Funktion im Fehlerfall aufzurufen; nur sollte diese dann auch die'en. Die Syntax des open-Befehls war natürlich falsch, aber ' &error' darf ruhig stehen bleiben.

      for ($f=0;$f<=$filesize;$f++) {

      for ($f=0; $f=$#lines;$f++) {
      oder gar
      for (0.. $#lines) {

      for (0..scalar @lines - 1)

      while ($_ ne /<!--SCRIPTENDE-->/) {

      Du meinst (wahrscheinlich)
      while ($_ ne '<!--SCRIPTENDE-->') {

      Ich tippe mehr auf
      while (!/<!--SCRIPTENDE-->/) {

      Wobei diese ganze $_-Zuweiserei vermutlich eher nachteilig ist:

      for (0..scalar @lines - 1) {
        if ($lines[$_] =~ /.../) {
          while ($lines[$_] !~ /.../) { ... }
        }
      }

      Hier erhoehst Du den Index ein zweitesmal, d.h. Du ueberspringst jedesmal eine Zeile.

      Ich glaube, das ist Absicht - und damit ein wunderbarer Grund, kein for zu benutzen. Setze initial

      my $f = 0;

      und benutze dann eine while-Schleife, in der _nur Du_ $f erhöhst.

      close (DATEI);

      Die war schreibend geöffnet, oder? Dann solltest Du auch hier den Fehlercode mit 'or die' oder von mir aus ' &error' abfangen.

      Kann sein, dass ich noch etwas uebersehen habe, den Code solltest Du aber auf jeden Fall noch mal ueberdenken.

      ACK :-)

      rename ($neue_html, $meine_html); # bei Bedarf

      Da würde ich noch ein unlink $meine_html vorsetzen; außerdem fährt man meist mit absoluten Serverpfaden besser...

      Cheatah

      1. hi,

        erstmal danke fuer eure hilfe, aber leider blicke ich nicht mehr so
        ganz durch. also...

        #!/path/to/perl -w
        use strict;

        was genau ist der grund fuer diesen syntax?

        open (DATEI>$meine_html) &error($errormsg.$!.')');

        open DATEI, ">$meine_html" or die "open DATEI: $!";

        ok ok, das komma ist mir abhanden gekommen beim konvertieren von
        unix-->dos ;-)  (auch mein windows-konvertier-prog ist nicht ganz
        fehlerfrei aber dafuer mir und schoen klein und schnell und mit allem
        was ich brauche und will ;-) )

        Es ist im Prinzip schon okay, eine eigene Funktion im Fehlerfall aufzurufen; nur sollte diese dann auch die'en. Die Syntax des open-Befehls war natürlich falsch, aber ' &error' darf ruhig stehen bleiben.

        sehe ich genauso ;-)

        for (0..scalar @lines - 1)

        sorry aber was heisst/bedeutet scalar?

        while ($_ ne /<!--SCRIPTENDE-->/) {

        Du meinst (wahrscheinlich)
        while ($_ ne '<!--SCRIPTENDE-->') {

        nicht so einfach, wegen returns - funzte bei mir so nicht.

        Ich tippe mehr auf
        while (!/<!--SCRIPTENDE-->/) {

        kommt schon eher hin

        Wobei diese ganze $_-Zuweiserei vermutlich eher nachteilig ist:

        inwiefern?

        for (0..scalar @lines - 1) {
          if ($lines[$_] =~ /.../) {

        scriptstart?

        while ($lines[$_] !~ /.../) { ... }

        scriptende dann ab in die datei?

        Hier erhoehst Du den Index ein zweitesmal, d.h. Du ueberspringst

        jedesmal eine Zeile.

        ist genauso gewollt - hintergedanke wenn ich einfach die zeilen ueberspringe bis $_ scriptende ist, dann duerfte er sie ja nicht mit reinschreiben (zumindest habe ich das aehnlich so frueher in tp7.0 gemacht)

        Ich glaube, das ist Absicht - und damit ein wunderbarer Grund, kein for zu benutzen. Setze initial

        1. absicht: s.o.  und 2. was ist initial?

        my $f = 0;

        und benutze dann eine while-Schleife, in der _nur Du_ $f erhöhst.

        wie meinst du das? _nur Du_

        close (DATEI);

        Die war schreibend geöffnet, oder? Dann solltest Du auch hier den Fehlercode mit 'or die' oder von mir aus ' &error' abfangen.

        tue ich ja.

        ACK :-)

        sch... schreibfaulen progammierer ;-) was heisst das?

        vielen dank bishierher und ich hoffe ich oute mich nicht zusehr als
        perl-neuling ;-)

        bye and happy coding Lars

        1. Hi,

          erstmal danke fuer eure hilfe, aber leider blicke ich nicht mehr so
          ganz durch. also...

          sorry, wenn ich Dich verwirrt habe.

          #!/path/to/perl -w
          use strict;

          was genau ist der grund fuer diesen syntax?

          Sichere Programmierung, Fehlervermeidung von Anfang an.

          for (0..scalar @lines - 1)

          sorry aber was heisst/bedeutet scalar?

          Ein Skalar ist sozusagen ein nulldimensionales Element - also ein String, eine Zahl usw. Im Gegensatz dazu gibt es die Liste (Arrays, Hashes etc.). Wenn Du ein Array mit dem Keyword "scalar" in den skalaren Kontext zwingst, wird die Zahl der Elemente zurückgegeben.

          while ($_ ne '<!--SCRIPTENDE-->') {

          nicht so einfach, wegen returns - funzte bei mir so nicht.

          Dagegen hilft chomp; aber wegen Leerzeichen an Anfang und Ende halte ich hier eine RegExp schon für okay (obwohl natürlich rechenintensiver).

          Wobei diese ganze $_-Zuweiserei vermutlich eher nachteilig ist:

          inwiefern?

          Könnte von anderen Dingen überschrieben werden.

          for (0..scalar @lines - 1) {
            if ($lines[$_] =~ /.../) {

          scriptstart?

          Die Punkte waren als Platzhalter gedacht :-) Der Code ist ansonsten an Deinem orientiert, deswegen habe ich ihn nicht weiter ausgeführt.

          Ich glaube, das ist Absicht - und damit ein wunderbarer Grund, kein for zu benutzen. Setze initial

          1. absicht: s.o.  und 2. was ist initial?

          initial = anfangs, zu Beginn (englisch "init")

          und benutze dann eine while-Schleife, in der _nur Du_ $f erhöhst.

          wie meinst du das? _nur Du_

          Kein "for" o.ä.

          close (DATEI);

          Die war schreibend geöffnet, oder? Dann solltest Du auch hier den Fehlercode mit 'or die' oder von mir aus ' &error' abfangen.

          tue ich ja.

          Nein, denn Du schreibst nicht

          close (DATEI) or die "Kann Datei nicht schliessen: $!";

          Auch beim Schließen kann es schief gehen, was aber nur bei Schreibzugriffen relevant ist.

          ACK :-)

          sch... schreibfaulen progammierer ;-) was heisst das?

          ACKnowledge = Zustimmung (Gegenteil: NACK)

          Das ist übrigens ein häufig verwendetes Steuerzeichen :-)

          vielen dank bishierher und ich hoffe ich oute mich nicht zusehr als
          perl-neuling ;-)

          Waren wir doch alle mal.

          Cheatah

          1. Hi,

            erstmal danke fuer eure hilfe, aber leider blicke ich nicht mehr so
            ganz durch. also...

            sorry, wenn ich Dich verwirrt habe.

            #!/path/to/perl -w
            use strict;

            was genau ist der grund fuer diesen syntax?

            Sichere Programmierung, Fehlervermeidung von Anfang an.

            werde mich bemuehen dies jetzt einzufuehren.

            for (0..scalar @lines - 1)

            sorry aber was heisst/bedeutet scalar?

            Ein Skalar ist sozusagen ein nulldimensionales Element - also ein String, eine Zahl usw. Im Gegensatz dazu gibt es die Liste (Arrays, Hashes etc.). Wenn Du ein Array mit dem Keyword "scalar" in den skalaren Kontext zwingst, wird die Zahl der Elemente zurückgegeben.

            ah ja, kling ja auch interessant, aber liefert ein normales @lines
            nicht auch schon die anzahl der zeilen zurueck?

            while ($_ ne '<!--SCRIPTENDE-->') {

            nicht so einfach, wegen returns - funzte bei mir so nicht.

            Dagegen hilft chomp; aber wegen Leerzeichen an Anfang und Ende halte ich hier eine RegExp schon für okay (obwohl natürlich rechenintensiver).

            also mit RegExp meinst du das /../ bzw. !/.../  !?

            Wobei diese ganze $_-Zuweiserei vermutlich eher nachteilig ist:

            inwiefern?

            Könnte von anderen Dingen überschrieben werden.

            ist bestimmt ne haeufige fehlerursache !?

            for (0..scalar @lines - 1) {
              if ($lines[$_] =~ /.../) {

            scriptstart?

            Die Punkte waren als Platzhalter gedacht :-) Der Code ist ansonsten an Deinem orientiert, deswegen habe ich ihn nicht weiter ausgeführt.

            sehr schoen, das ich wenigstens etwas scheinbar richtig gemacht habe.

            Ich glaube, das ist Absicht - und damit ein wunderbarer Grund, kein for zu benutzen. Setze initial

            1. absicht: s.o.  und 2. was ist initial?

            initial = anfangs, zu Beginn (englisch "init")

            i speak english very well but leider nich ganz so schnell ;-)

            und benutze dann eine while-Schleife, in der _nur Du_ $f erhöhst.

            wie meinst du das? _nur Du_

            Kein "for" o.ä.

            also z.b. $f++

            close (DATEI);

            Die war schreibend geöffnet, oder? Dann solltest Du auch hier den Fehlercode mit 'or die' oder von mir aus ' &error' abfangen.

            tue ich ja.

            Nein, denn Du schreibst nicht

            close (DATEI) or die "Kann Datei nicht schliessen: $!";

            Auch beim Schließen kann es schief gehen, was aber nur bei Schreibzugriffen relevant ist.

            ach du beziehst dich hier auf eine eventuelle fehlermeldung.?
            das close habe ich aber trotzdem getippt.

            ACK :-)

            sch... schreibfaulen progammierer ;-) was heisst das?

            ACKnowledge = Zustimmung (Gegenteil: NACK)

            Das ist übrigens ein häufig verwendetes Steuerzeichen :-)

            wird gemerkt...

            vielen dank bishierher und ich hoffe ich oute mich nicht zusehr als
            perl-neuling ;-)

            Waren wir doch alle mal.

            Cheatah

            aller anfang ist schwer ;-)  kenne ich von TP und VB und ganz am
            anfang 8bit-C64-Basic.

            also dann ne ruhige nacht und bye

            lars

            1. Hi,

              Ein Skalar ist sozusagen ein nulldimensionales Element - also ein String, eine Zahl usw. Im Gegensatz dazu gibt es die Liste (Arrays, Hashes etc.). Wenn Du ein Array mit dem Keyword "scalar" in den skalaren Kontext zwingst, wird die Zahl der Elemente zurückgegeben.

              ah ja, kling ja auch interessant, aber liefert ein normales @lines
              nicht auch schon die anzahl der zeilen zurueck?

              nur im skalaren Kontext. Beispielsweise gibt

              print @array;

              das gesamte Array aus; hingegen

              print scalar @array;

              nur die Anzahl der Felder.

              Dagegen hilft chomp; aber wegen Leerzeichen an Anfang und Ende halte ich hier eine RegExp schon für okay (obwohl natürlich rechenintensiver).

              also mit RegExp meinst du das /../ bzw. !/.../  !?

              Ja.

              Wobei diese ganze $_-Zuweiserei vermutlich eher nachteilig ist:

              inwiefern?

              Könnte von anderen Dingen überschrieben werden.

              ist bestimmt ne haeufige fehlerursache !?

              Wenn man Schleifen o.ä. verschachtelt und nicht höllisch aufpaßt schon.

              was ist initial?

              initial = anfangs, zu Beginn (englisch "init")

              i speak english very well but leider nich ganz so schnell ;-)

              In initium latinum erat ;-)

              (Oder so ähnlich, mein Latein ist ein wenig lange her... ich kenne nur noch "Sita us vi late in isis abanet" ;-)

              und benutze dann eine while-Schleife, in der _nur Du_ $f erhöhst.
              also z.b. $f++

              Genau.

              close (DATEI) or die "Kann Datei nicht schliessen: $!";

              Auch beim Schließen kann es schief gehen, was aber nur bei Schreibzugriffen relevant ist.

              ach du beziehst dich hier auf eine eventuelle fehlermeldung.?

              Ja. Gerade beim Schließen von geschriebenen Dateien ist ein Fehler meistens fatal.

              aller anfang ist schwer ;-)  kenne ich von TP und VB und ganz am
              anfang 8bit-C64-Basic.

              FOR T = 0 TO 15: FOR Z = 0 TO 15: POKE 53280,T: POKE 53281,Z: NEXT: NEXT ;-)

              Cheatah

              1. hi,

                FOR T = 0 TO 15: FOR Z = 0 TO 15: POKE 53280,T: POKE 53281,Z: NEXT: NEXT ;-)

                ich sehe wir verstehen uns ;-)

                ok, ich probier mal noch ein bischen damit rum, rueckmeldung folgt...

                bye lars

                1. ein froehliches hidiho,

                  man ersetze die erste for-schleife durch ne while-schleife
                  und es klappt perfekt, auch wenn kein altes script vorhanden ist ;-)

                  da ich in der for-schleife $f++ hatte und spaeter nochmal, $f++
                  gemacht habe, hat er gleich um 2 erhoeht, und konnte ja nur falsch
                  sein. ;-)
                  ein ausdrucken von $f in die datei an den zeilenanfang hat dann die
                  wahrheit ans licht gebracht.

                  $f=0;
                  while ($f <= $filesize) {
                    $_ = $lines[$f];
                    if (/<!--SCRIPTSTART-->/) {
                      while (!/<!--SCRIPTENDE-->/) {
                       $f++;                 # wichtig auch, das dieses hier steht.
                       $_ = $lines[$f];      # hier werden die zuloeschenden zeilen
                                             # uebersprungen @kai ;-)
                      }
                     print DATEI '<!--SCRIPTSTART-->'."\n";
                    }
                  print DATEI $_;
                  $f++;
                  }

                  danke kai & cheatah

                  bye lars