Kai: Datei nach X Zeilen löschen

Hallo zusammen

Ich habe ein kleines Problem. Ich habe eine kleine Log-Datenbank (Text-DB). Bei dieser Datenbank kommen laufend Einträge per Script hinzu (Zeilen weise). Ich möchte nun, dass die Datenbank nicht mehr als zB. 30 Zeilen hat.

Die Datenbank schreibe ich so:

open (DAT , ">> $archiv") ;
flock(DAT,2) if ($lock==1) ;
print DAT "$date|$time|$phone|$msg|\n" ;
close (DAT) ;

Nur, wie kann ich nun machen, dass die DB nicht grösser als 30 Zeilen wird? Kann mir da jemand auf die Sprünge helfen?

Herzlichen Dank schon mal.

KAI

  1. so vielleicht:

    open(BACKUP, $archiv);
            @ALLBACKUP = <BACKUP>;
            close(BACKUP);
            #.:.:.:.:.:.:.:.:.
            $mycount = 1;
            open (DAT , ">$archiv") ;
            foreach $einbackup(@ALLBACKUP)
            {
                if($mycount < 30){
                   $mycount = $mycount + 1;
                   print DAT "$einbackup";
                }
            }
            close (DAT) ;

    Gruß
    Girom

    1. Hi Girom

      Danke für Deine Antwort! So geht es wirklich.

      Gibt es auch die Möglichkeit das ganze zu einer Routine zusammen zufassen? Also Eintrag in DB machen und gleich checken sie nicht grösser als 30 Zeilen ist. Oder ist es besser das in zwei Schritten zu machen?

      Danke und Gruss

      KAI

      1. Hi Kai,

        gern geschehen - bestimmt ist es möglich, ich kann dir nur leider nicht sagen wie - ich selbst benutze lieber 2 Schritte.

        Bei dir müsste das dann so aussehen:

        open(BACKUP, ">>$archiv");
                print BACKUP " neue daten \n";
                close(BACKUP);
                #.:.:.:.:.:.:.
                open(BACKUP, $archiv);
                @ALLBACKUP = <BACKUP>;
                close(BACKUP);
                #.:.:.:.:.:.:.
                $maxmycount = 1;
                foreach $einbackup(@ALLBACKUP)
                {
                   $maxmycount = $maxmycount + 1; # zählen aller zeilen
                }
                $maxmycount = $maxmycount - 30;   # maximale Zeilen
                #.:.:.:.:.:.:.
                $mycount = 1;
                open (DAT , ">$archiv") ;
                foreach $einbackup(@ALLBACKUP)
                {
                    if($mycount > $maxmycount){
                       $mycount = $mycount + 1;
                       print DAT "$einbackup";
                    }
                }
                close (DAT) ;

        Wobei mit >> die neuen Daten unten angehängt werden, wodurch sogar noch eine Abfrage nötig wäre (an alle Perl-Profis, ich weiß es ist nicht der schönste, und kürzeste Code - aber er arbeitet!) da sonst immer die neuen Daten gelöscht werden.

        Hoffe das geht noch immer :)

        Gruß
        Girom

        1. Hey Girom

          So, ich habs jetzt geschafft die Schritte zusammen zu fügen.
          Das Prolem, dass die Einträge nicht am Ende sonder am Anfang der DB eingetragen weren, kann man mit unshift(@array,"neuerEintarag"); lösen.

          Gruss KAI

          DB einlesen

          open(ARCHIVDB,"<$pfaddb");
          @ALLARCHIVDB = <ARCHIVDB>;
          close(ARCHIVDB);

          neuer DB-Eintrag am Anfabg des Array anfügen

          unshift(@ALLARCHIVDB,"$date|$time|$msg|\n");

          DB wieder in Text-Datei schreiben

          $mycount = 1;
          open (DAT,">$pfaddb") ;
          foreach $getline(@ALLARCHIVDB)
           {
           if($mycount < 11)
            {
            $mycount = $mycount + 1;
            print DAT $getline;
            }
           }
          close (DAT) ;

          1. gudn tach!

            foreach $getline(@ALLARCHIVDB)
            {
            if($mycount < 11)
              {
              $mycount = $mycount + 1;
              print DAT $getline;
              }
            }

            nicht wichtig, aber das geht imho noch etwas kuerzer _und_ huebscher:

              
            for(my $i=0;$i<11;++$i){  
             print DAT $ALLARCHIVDB[$i];  
            }
            

            (und schneller wird's wohl auch sein.)

            prost
            seth

            1. Hallo,

              nicht wichtig, aber das geht imho noch etwas kuerzer _und_ huebscher:

              for(my $i=0;$i<11;++$i){
              print DAT $ALLARCHIVDB[$i];
              }

              
              >   
              > (und schneller wird's wohl auch sein.)  
                
              ~~~perl
                
                print DAT $ALLARCHIVDB[$_] foreach(0..10);  
              
              

              gruss

              --
              no strict;
              no warnings;
              Meine Signatur hat Urlaub.
            2. Hallo,

              nicht wichtig, aber das geht imho noch etwas kuerzer _und_ huebscher:

              for(my $i=0;$i<11;++$i){
              print DAT $ALLARCHIVDB[$i];
              }

                
                noch einer :)  
              ~~~perl
                
                print DAT $ALLARCHIVDB[$_] for 0..10;  
              
              

              gruss

              --
              no strict;
              no warnings;
              Meine Signatur hat Urlaub.
          2. DB einlesen

            open(ARCHIVDB,"<$pfaddb");
            @ALLARCHIVDB = <ARCHIVDB>;
            close(ARCHIVDB);

            neuer DB-Eintrag am Anfabg des Array anfügen

            unshift(@ALLARCHIVDB,"$date|$time|$msg|\n");

            DB wieder in Text-Datei schreiben

            $mycount = 1;
            open (DAT,">$pfaddb") ;
            foreach $getline(@ALLARCHIVDB)
            {
            if($mycount < 11)
              {
              $mycount = $mycount + 1;
              print DAT $getline;
              }
            }
            close (DAT) ;

            Falls dies ein CGI Skript ist, werden dir früher oder später Einträge verloren gehen. zwischen dem 1.close und den 2.open kann durchaus ein neuer Prozeß auf die Datei zugreifen und diese einlesen in dem Moment wird der Eintrag vom ersten Prozeß sofort wieder verschwinden.

            Du musst die Datei zum lesen und schreiben öffnen und flocken. In etwa so

            #!/usr/bin/perl -w  
            use strict;  
            use Fcntl qw(SEEK_SET LOCK_EX);  
              
            my $flock = 1;  
            my $pfaddb = 'test.txt';  
            my $daten = 'test';  
            my $max = 10;  
              
            open FH, ">$pfaddb" or die "Kann $pfaddb nicht öffnen, weil:$!";  
            for(0..20)  
            {  
            print FH "$_.$daten\n";  
            }  
            close FH;  
              
            open FH, "+<$pfaddb" or die "Kann $pfaddb nicht öffnen, weil:$!";  
            flock(FH, LOCK_EX) if $flock;  
            seek FH, 0,SEEK_SET;  
            my $count = 0;  
            while(<FH>)  
            {  
                $count++;  
                last if $count == $max;  
            }  
            my $pos = tell FH;  
            truncate FH, $pos or die $!;  
            seek FH, $pos, SEEK_SET;  
            print FH "neu-$daten\n";  
            close FH;
            

            Struppi.