zeile aus textfile entfernen oder ausschneiden
Alain
- perl
Hallo leute,
habe leider wieder ein problem,wo ich seit stunden probiere,einerseits
aus schnipsels von selhtml und anderen perlscripts,aber ich kriegs nicht hin.
Das problem ist wie folgt:
Ich habe eine textdatei welche einträge von waren|preis|anzahl beinhaltet bsp. der textdatei:
datum|ipadresse|
ware1|20.00|1|
ware2|25.00|1|
...
im perlsscript steht:
sub delete_item {
open (REFFILE,"$reffile")||error('cannot open cart ');
my @newlines = ();
my @lines=<REFFILE>;
close(REFFILE);
my $items = $FORM{'Video(s)'};#wird vom formular geschickt
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
foreach (@lines)
{
push (@newlines,$_) if ($_ !~ /^$items|/i);
my $newfile = join("|",@newlines);
}
open (REFFILE,">$reffile")||error('cannot open file for write');
print REFFILE "$newfile\n";
close(REFFILE);
}
entweder löscht das script alles oder aber es steht anschliessend nur das datum und ip eintrag drinnen.
Was kann da noch fehlen?
Grüsse vom
Alain
Hallo,
my $nf;
foreach (..)
{
[..]
push ( @newlines, $_ ) if ( $_ !~ /^$items|/i );
my $nf.= join( '|', @newlines );
}
Schau mal in Selfhtml nach dem .= Operator.
Bert
Ich habe eine textdatei welche einträge von waren|preis|anzahl beinhaltet bsp. der textdatei:
Du hast eine Datenbank.
datum|ipadresse|
ware1|20.00|1|
ware2|25.00|1|
Wenn dir mySQL oder ähnliches zu kompliziert ist (früher oder später sollte man sich damit trotzdem auseinadersetzen - ich hab aber zugegeben auch einige Jahre mcih davor gedrückt), dann sei dir das Modul DB_File an Herz gelegt, damit kannst du solche Sachen wesentlich einfacher bewerkstelligen.
...
im perlsscript steht:
sub delete_item {
open (REFFILE,"$reffile")||error('cannot open cart ');
Ich weißß nicht ob dir das schon erzählt wurde. In $! steht warum das öffent scheitert, das kann u.U. nützlich sein.
my @newlines = ();
my @lines=<REFFILE>;
close(REFFILE);
Hier schon mal, deine Vorgehensweise kann u.U. zu Datenverlust führen, wenn hier in dem Augenblick eine anderes Programm auf die Datei zugreift, kann es passieren das die Daten, die du unten eintragen willst verschwinden. Und kann heißt in solch einem Falle fast immer, es wird passieren.
(ausser das Skript ist lokal und du bist der einzige der es nutzt)
Es gibt Möglichkeiten dies zu verhindern, Stichwort 'flock'
my $items = $FORM{'Video(s)'};#wird vom formular geschickt
Du arbeitest immer noch nicht mit CGI.pm?
Du bist sicher das in dem Eintrag ein Wert steht?
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
Was ist den $_ hier an dieser stelle?
foreach (@lines)
Weiter oben bist du bereits alle Einträge durch gegangen (while <REFILE>) und jetzt nochmal?
Das ist evtl. eine grosse Verschwendung je nachdem wie gross diese Datei ist.
Es gibt die Möglichkeit Dateien zum lesen und schreiben zu öffnen.
{
push (@newlines,$_) if ($_ !~ /^$items|/i);
my $newfile = join("|",@newlines);
Was hier passiert ist völlig wirr.
Wenn in der aktuellen Zeile $items vorkommt, dann push es auf das array. Dann wird das Array mit den Zeichen '|' zusammengefügt und einer lokal gültigen Variabel zugewiesen.
}
$newline existiert hier nicht mehr.
open (REFFILE,">$reffile")||error('cannot open file for write');
print REFFILE "$newfile\n";
und daraus läßt sich vermuten, dass du auch nicht mit use strict arbeitest, dann wäre das gar nicht möglich, denn $newline ist undefiniert.
close(REFFILE);
}
entweder löscht das script alles oder aber es steht anschliessend nur das datum und ip eintrag drinnen.
Was kann da noch fehlen?
Hmm? Eine Logik?
Wie gesagt DB_File ist für solch einen Fall wesentlich günstger.
Ich hab mal gekramt, so würde das z.b. aussehen:
#!/usr/bin/perl -w
use strict;
use DB_File;
use Fcntl qw(O_RDWR O_CREAT);
my $file = 'test.db';
my %daten;
my $DBH = tie %daten, 'DB_File', $file, O_RDWR|O_CREAT, 0777;
save('test', 1.99, 50);
save('test1', 1.99, 50);
save('test2', 1.99, 50);
print "Daten:\n\n";
foreach(keys %daten)
{
my $d = get($_);
print "Produket:$d->{name} = $d->{itemprice} $d->{itemquant} \n";
}
print "lösche test1....\n";
del('test1');
print "Daten:\n\n";
foreach(keys %daten)
{
my $d = get($_);
print "Produket:$d->{name} = $d->{itemprice} $d->{itemquant} \n";
}
sub save
{
my($itemname, $itemprice, $itemquant) = @_;
$daten{$itemname} = "$itemprice|$itemquant";
}
sub get
{
my $name = shift || return;
return unless exists $daten{$name};
my @tmp = split '|', $daten{$name};
my $item = {
name => $name,
itemprice => $tmp[0],
itemquant => $tmp[1]
};
return $item;
}
sub del
{
my $name = shift || return;
delete $daten{$name};
}
Struppi.
Hi struppi,
Ich habe eine textdatei welche einträge von waren|preis|anzahl beinhaltet bsp. der textdatei:
Du hast eine Datenbank.
nö,das ist eine temporäre datei,die auch nie gross sein kann,weil
mit if ((stat($reffile))[7] > 1000); nicht grösser als 1000 byte...
datum|ipadresse|
ware1|20.00|1|
ware2|25.00|1|Wenn dir mySQL oder ähnliches zu kompliziert ist (früher oder später sollte man sich damit trotzdem auseinadersetzen - ich hab aber zugegeben auch einige Jahre mcih davor gedrückt)...
naja...kenn ich hab ich auch schon zu tun gehabt.
open (REFFILE,"$reffile")||error('cannot open cart ');
Ich weißß nicht ob dir das schon erzählt wurde. In $! steht warum das öffent scheitert, das kann u.U. nützlich sein.
ja es öffnet 100%
my @newlines = ();
my @lines=<REFFILE>;
close(REFFILE);Hier schon mal, deine Vorgehensweise kann u.U. zu Datenverlust führen, wenn hier in dem Augenblick eine anderes Programm ...
Es gibt Möglichkeiten dies zu verhindern, Stichwort 'flock'
ja ich nutzte flock und auch use strict sowie use CGI ganz am anfang
das hier war nur der sub.
das ist nur ein haubt schnipsel dess vorganges in wircklichkeit steht
das schon drinn was Du meinst.
my $items = $FORM{'Video(s)'};#wird vom formular geschickt
Du arbeitest immer noch nicht mit CGI.pm?
Du bist sicher das in dem Eintrag ein Wert steht?
ja!auch schon probiert mit print "$items...
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
Was ist den $_ hier an dieser stelle?
sollten die daten sein die in der textfile stehen.
foreach (@lines)
Weiter oben bist du bereits alle Einträge durch gegangen (while <REFILE>) und jetzt nochmal?
while seh ich nicht :)
{
push (@newlines,$_) if ($_ !~ /^$items|/i);
my $newfile = join("|",@newlines);Was hier passiert ist völlig wirr.
eben wirrt mich auch etwas...
ich möchte nach einer zeile suchen und löschen wenn sie existiert,
fertig mehr nicht.
Wenn in der aktuellen Zeile $items vorkommt, dann push es auf das array. Dann wird das Array mit den Zeichen '|' zusammengefügt und einer lokal gültigen Variabel zugewiesen.
}
und daraus läßt sich vermuten, dass du auch nicht mit use strict arbeitest, dann wäre das gar nicht möglich, denn $newline ist undefiniert.
doch my $newfile = join("|",@newlines);
close(REFFILE);
}
entweder löscht das script alles oder aber es steht anschliessend nur das datum und ip eintrag drinnen.
Was kann da noch fehlen?Hmm? Eine Logik?
Wie gesagt DB_File ist für solch einen Fall wesentlich günstger.
ja kenn ich hab ich schon gemacht mit,aber ich möchte jetzt das script nicht für eine db umbauen nur wegen der sub das eine zeile
entfernt.Es war eigentlich gedacht dafür um waren aus dem
waren korb auf einer webseite zu entfernen,das heisst wenn man
auf den entsprechenden delete link klickt wird nach der zeile
im textfile gesucht und ersetzt durch nichts-fertig textfile schliessen,seite refreshen...
Ich hab mal gekramt, so würde das z.b. aussehen:
#!/usr/bin/perl -w
use strict;
use DB_File;
use Fcntl qw(O_RDWR O_CREAT);
nö das brauch ich nicht danke.
das script funtzt sonst schon alles wurde definiert...und läuft mit use stricht wie gesagt und auch mit LOCK_EX...
ich habe da noch den anderen schnipsel vom ursprünglichen script
sub delete_item {
open (REFFILE,"$reffile") || print "Content-type: text/html\n\n Can't Open $reffile(r): $!\n";
@LINES=<REFFILE>;
close(REFFILE);
$SIZE=@LINES;
open (REFFILE,">$reffile") || print "Content-type: text/html\n\n Can't Open $reffile(r): $!\n";
print REFFILE "$date| $ENV{'REMOTE_HOST'}| $ENV{'HTTP_USER_AGENT'}|NULL|NULL|\n";
for ($i=1;$i<$SIZE;$i++) {
$_=$LINES[$i];
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
if ($FORM{$itemname} eq $itemname) {
}
else { print REFFILE $_; }
}
close(REFFILE);
print "Location: $cgiurl?command=review\n\n";
}
damit gehts auch nicht.
Gruss
Alain
hi nochmal,
so jetzt gehts ja doch
hier hab ich den neuen code,falls es jemand interessiert:
sub delete_item {
open (REFFILE,"$reffile")||error('cannot open cart file for read delete_item');;
my @LINES=<REFFILE>;
close(REFFILE);
my $SIZE=@LINES;
my $itemns = $FORM{'Video(s)'};
open (REFFILE,">$reffile")||error('cannot open cart file for write delete_item');;
flock(REFFILE, LOCK_EX)||error('cannot lock cart for write delete_item');
print REFFILE "$date| $host|\n";
for (my $i=1;$i<$SIZE;$i++) {
$_=$LINES[$i];
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
if ($itemns eq $itemname) {
}
else { print REFFILE $_; }
}
close(REFFILE);
print "Location: $cgiurl?command=review\r\n\r\n";
}
Grüsse vom
Alain
so jetzt gehts ja doch
hier hab ich den neuen code,falls es jemand interessiert:Delete an item from the cart
sub delete_item {
open (REFFILE,"$reffile")||error('cannot open cart file for read delete_item');;
Nach wie vor verstehe ich nicht, warum du nicht die Fehlermeldung ausgibst , auch wenn du 100% überzeugt bist das kein Fehler Auftritt, es wäre ein leichtes:
open (REFFILE,"$reffile")||error("cannot open cart file for read delete_item, reason: $!";;
my @LINES=<REFFILE>;
close(REFFILE);
my $SIZE=@LINES;
my $itemns = $FORM{'Video(s)'};
open (REFFILE,">$reffile")||error('cannot open cart file for write delete_item');;
wie gesagt man kann Dateien auch zum lesen und schreiben öffnen, es kann unter Umständen passieren, das zwischen close und open ein anderer Prozess zugreift und das führt zu Datenverlust.
for (my $i=1;$i<$SIZE;$i++) {
$_=$LINES[$i];
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
foreach( @line)
{
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
würde reichen.
if ($itemns eq $itemname) {
Do nothing
}
else { print REFFILE $_; }
}
print REFFILE $_ if $itemns ne $itemname;
würde reichen.
Struppi.
naja...kenn ich hab ich auch schon zu tun gehabt.
open (REFFILE,"$reffile")||error('cannot open cart ');
Ich weißß nicht ob dir das schon erzählt wurde. In $! steht warum das öffent scheitert, das kann u.U. nützlich sein.
ja es öffnet 100%
100% gibt es nicht, und schon gar nicht bei einer CGI Anwendung.
my $items = $FORM{'Video(s)'};#wird vom formular geschickt
Du arbeitest immer noch nicht mit CGI.pm?
Du bist sicher das in dem Eintrag ein Wert steht?ja!auch schon probiert mit print "$items...
Ich meine - immer?
Du prüfst in einem CGI Programm nicht einen Wert der eingeben werden kann, das kann zu einem Fehlerhaften verhalten führen.
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
Was ist den $_ hier an dieser stelle?
sollten die daten sein die in der textfile stehen.
ist es aber nicht.
foreach (@lines)
Weiter oben bist du bereits alle Einträge durch gegangen (while <REFILE>) und jetzt nochmal?
while seh ich nicht :)
Mein fehler.
{
push (@newlines,$_) if ($_ !~ /^$items|/i);
my $newfile = join("|",@newlines);Was hier passiert ist völlig wirr.
eben wirrt mich auch etwas...
ich möchte nach einer zeile suchen und löschen wenn sie existiert,
fertig mehr nicht.Wenn in der aktuellen Zeile $items vorkommt, dann push es auf das array. Dann wird das Array mit den Zeichen '|' zusammengefügt und einer lokal gültigen Variabel zugewiesen.
}
und daraus läßt sich vermuten, dass du auch nicht mit use strict arbeitest, dann wäre das gar nicht möglich, denn $newline ist undefiniert.
doch my $newfile = join("|",@newlines);
Aber nur inerhalb von { ... } my deklariert eine Variabel innerhalb eines Blocks, danach existiert sie nicht mehr.
Insofern glaub ich auch nicht das das Beispiel strict war:
Probier das mal aus:
use strict;
{
my $test = '';
}
print $text;
Es läuft nicht.
Struppi.
Hi,
Probier das mal aus:
use strict;
{
my $test = '';
}
print $text;
Es läuft nicht.
Wie sollte es auch, nicht mal die Namen der beiden Variablen sind identisch ;-)
cu,
Andreas
Es läuft nicht.
Wie sollte es auch, nicht mal die Namen der beiden Variablen sind identisch ;-)
Peinlich :-(
Aber auch das läuft nicht:
#! /usr/bin/perl -w
use strict;
{
my $test = '';
}
print $test ;
Struppi.
hi struppi,
100% gibt es nicht, und schon gar nicht bei einer CGI Anwendung.
da hast Du recht
my $items = $FORM{'Video(s)'};#wird vom formular geschickt
Du arbeitest immer noch nicht mit CGI.pm?
ja das ist mitlerweile ein problem,ich möchte das jetzt doch mit
CGI.pm machen,weil es mitlerweile so nicht ganz geht wie es jetzt ist,jedenfalls nicht mit dem alten browser netscape 4.x mit den anderen gehts NS7,IE5...
eine frage dazu ist,wenn ich in einer sub welches gleichzeitig ein teil einer html ausgabe ist,den eintrag
<input type='hidden' name='$rcitem-desc' value='$itemname'> sowie einen link href='$cgiurl?command=delitem&$rcitem-desc=$itemname' habe,das dann an das selbige script geschickt wird,aber dann eben die sub delitem(wie unten beschrieben) aufruft,wie kann ich das dann mit CGI.pm einbinden?Ich müsste doch auf den name='$rcitem-desc' dort (sub delete_item) zugreifen oder?
if($FORM{$rcitem-desc} eq $itemname) oder so...
Soll ich z.B.
my $rcitem-desc = $FORM{'rcitem-desc'}||'';
ganz am anfang vom script deklarieren oder erst in der sub?
Du bist sicher das in dem Eintrag ein Wert steht?
nö mitlerweile nicht mehr,da es wie gesagt mit NS4.x nicht geht.
Ich habe mich mal in selfhtml schlau gemacht,aber werde da nicht ganz schlau draus um ehrlich zu sein ;-)
Das script wird zur zeit so deklariert bzw. geparst
my %FORM = parse_form();
my $command = $FORM{'command'}||'';
sub parse_form {
my %FORM;
my $query = new CGI;
my @names = $query->param;
foreach (@names){
$FORM{$_} = $query->param($_);
}
return %FORM;
}
ja!auch schon probiert mit print "$items...
Ich meine - immer?
Du prüfst in einem CGI Programm nicht einen Wert der eingeben werden kann, das kann zu einem Fehlerhaften verhalten führen.
stimmt :)
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
Was ist den $_ hier an dieser stelle?
sollten die daten sein die in der textfile stehen.ist es aber nicht.
ja aber $itemname ist definiert
grüsse
Alain
my $items = $FORM{'Video(s)'};#wird vom formular geschickt
Du arbeitest immer noch nicht mit CGI.pm?
ja das ist mitlerweile ein problem,ich möchte das jetzt doch mit
CGI.pm machen,weil es mitlerweile so nicht ganz geht wie es jetzt ist,jedenfalls nicht mit dem alten browser netscape 4.x mit den anderen gehts NS7,IE5...
Ein CGI Skript hat nichts mit dem Browser zu tun, du hast bvermutlich ein anderes Problem.
eine frage dazu ist,wenn ich in einer sub welches gleichzeitig ein teil einer html ausgabe ist,den eintrag
<input type='hidden' name='$rcitem-desc' value='$itemname'> sowie einen link href='$cgiurl?command=delitem&$rcitem-desc=$itemname' habe,das dann an das selbige script geschickt wird,aber dann eben die sub delitem(wie unten beschrieben) aufruft,wie kann ich das dann mit CGI.pm einbinden?Ich müsste doch auf den name='$rcitem-desc' dort (sub delete_item) zugreifen oder?
Das verstehe ich nicht.
Mit dem Modul kannst du acuh einfach die HTML ausgabe erzeugen:
CGI::hidden(-name => 'rcitem-desc', -value => $itemname);
gleichzeitig werden die Felder auch automatisch ausgefüllt, d.h. hier muss i.d.R. noch nicht mal '.value' stehen.
Und auf die Werte greifst du mit:
CGI::param('rcitem-desc');
zu.
Schau dir die Doku zu dem Modul mal an, was es alles kann.
if($FORM{$rcitem-desc} eq $itemname) oder so...
Soll ich z.B.
my $rcitem-desc = $FORM{'rcitem-desc'}||'';
ganz am anfang vom script deklarieren oder erst in der sub?
my deklariert eine Variabel lokal, du solltest sie dort deklarieren, wo du sie brauchst, wenn du sie im ganzen Programm an vielen Stellen brauchst kannst du sie auch im Aussnahmefall global deklarieren. Aber globale Variabel sind nicht besonders geschickt, da sie auch global verändert werden könnten und dann weiß man nie welchen Wert sie haben.
Es gibt aber auch z.b. die Möglichkeit mit packages ein Modul zu konstruieren in dem ein Variabel gültig ist. aber ich befürchte das überfordert dich.
Das script wird zur zeit so deklariert bzw. geparst
Parse form input
my %FORM = parse_form();
Get command variables
my $command = $FORM{'command'}||'';
parse form input
sub parse_form {
my %FORM;
my $query = new CGI;
my @names = $query->param;
foreach (@names){
$FORM{$_} = $query->param($_);
}
return %FORM;
}
Mit CGI.pm sieht das so aus:
my $command = CGI::param('command') ||'';
mehr brauchst du nicht. Ich verstehe nicht warum du glaubst hier ein HASH zu erzeugen müssen. du kannst jederzeit im Modul auf die Werte zugreifen, wie schon gesagt am sinnvollsten dort wo sie gebraucht werden.
my($itemname, $itemprice, $itemquant) = split(/|/,$_);
Was ist den $_ hier an dieser stelle?
sollten die daten sein die in der textfile stehen.ist es aber nicht.
ja aber $itemname ist definiert
Hat aber einen undefnierten Wert (je nachdem was in $_ steht, das weißt du aber hier nicht)
Struppi.
hi,
Ein CGI Skript hat nichts mit dem Browser zu tun, du hast bvermutlich ein anderes Problem.
hab ich gemerkt -> https://forum.selfhtml.org/?t=96253&m=585075
Mit dem Modul kannst du acuh einfach die HTML ausgabe erzeugen:
CGI::hidden(-name => 'rcitem-desc', -value => $itemname);
gleichzeitig werden die Felder auch automatisch ausgefüllt, d.h. hier muss i.d.R. noch nicht mal '.value' stehen.
cool :)
Und auf die Werte greifst du mit:
CGI::param('rcitem-desc');zu.
Schau dir die Doku zu dem Modul mal an, was es alles kann.
if($FORM{$rcitem-desc} eq $itemname) oder so...
Soll ich z.B.
my $rcitem-desc = $FORM{'rcitem-desc'}||'';
ganz am anfang vom script deklarieren oder erst in der sub?my deklariert eine Variabel lokal, du solltest sie dort deklarieren, wo du sie brauchst, wenn du sie im ganzen Programm an vielen Stellen brauchst kannst du sie auch im Aussnahmefall global deklarieren. Aber globale Variabel sind nicht besonders geschickt, da sie auch global verändert werden könnten und dann weiß man nie welchen Wert sie haben.
Es gibt aber auch z.b. die Möglichkeit mit packages ein Modul zu konstruieren in dem ein Variabel gültig ist. aber ich befürchte das überfordert dich.
Das script wird zur zeit so deklariert bzw. geparst
Parse form input
my %FORM = parse_form();
Get command variables
my $command = $FORM{'command'}||'';
parse form input
sub parse_form {
my %FORM;
my $query = new CGI;
my @names = $query->param;
foreach (@names){
$FORM{$_} = $query->param($_);
}
return %FORM;
}Mit CGI.pm sieht das so aus:
my $command = CGI::param('command') ||'';
mehr brauchst du nicht. Ich verstehe nicht warum du glaubst hier ein HASH zu erzeugen müssen. du kannst jederzeit im Modul auf die Werte zugreifen, wie schon gesagt am sinnvollsten dort wo sie gebraucht werden.
naja $FORM{$variable} kommt oft vor im script desshalb.
würde
my $FORM = CGI::param('FORM') ||'';
auch passen?
Grüsse
Alain