Datei nach X Zeilen löschen
Kai
- perl
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
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
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
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
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
open(ARCHIVDB,"<$pfaddb");
@ALLARCHIVDB = <ARCHIVDB>;
close(ARCHIVDB);
unshift(@ALLARCHIVDB,"$date|$time|$msg|\n");
$mycount = 1;
open (DAT,">$pfaddb") ;
foreach $getline(@ALLARCHIVDB)
{
if($mycount < 11)
{
$mycount = $mycount + 1;
print DAT $getline;
}
}
close (DAT) ;
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
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
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
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.