Sascha Müller: Hilfe zu Dateiverarbeitung

Beitrag lesen

Hallo Klaus,

Hallo,

my $textzeile=sekunden&&$aktuelle_ip\n;

Du meinst sicher
my $textzeile="$sekunden&&$aktuelle_ip\n";

Ja, natürlich :-)

Wobei ich anmerken will, daß ein Trennzeichen vollkommen ausreichen würde.

O.k., hast eigentlich auch wieder Recht...

usw... Ich glaube, das Hineinschreiben bekomme ich hin, das wird nur anhängendes Schreiben sein, und da zu einer Zeit immer nur ein User das Script ausführen kann, kann es auch nur immer eine Zeile sein, also kein Problem.

Ganz so einfach ist es nicht. Du solltest bedenken, daß ein Webserver mehrere Requests gleichzeitig bearbeiten kann, wodurch auch potentiell gleichzeitige Zugriffe auf diese Datei erfolgen könnten. die Funktion flock() solltest Du Dir daher genauer ansehen.

O.k., sperren ist vielleicht nicht verkehrt, werde ich mit einbauen

Außerdem solltest Du zum einen verhindern, daß eine IP-Adresse doppelt vorkommt, zum anderen, daß die Datei bei Zeiten auch wieder aufgeräumt wird, damit sie nicht zu groß wird.

Beim ersten Lesedurchgang der Datei soll - bevor überhaupt etwas anderes gemacht wird - alle Zeileneinträge die älter als 15 Minuten sind, "Gelöscht" werden. Da ein direktes Löschen einer Zeile in Perl nicht möglich ist!?!?, überlese ich diese Zeilen, alle jüngeren merke ich mir, und schreibe sie später wieder zurück. Habe ich also berücksichtigt.

Wie bekomme ich diese Daten wieder sauber aus dieser Textdatei heraus, so dass der erste Wert (Sekunden) auch wieder numerisch ist, und sich damit rechnen lässt.

In Perl gibt eis keine Datentypen, daher können Variableninhalte einmal als Zahl, ein andermal als Text verwendet werden.

my $wasauchimmer = "1234";
my $wasanderes = $wasauchimmer - 4;
print $wasanderes; # gibt 1230 aus

Kenne ich, aber ich habe es schon geschafft, EINE Zeile aus der Datei auszulesen, habe diesen von einem anderen Wert abgezogen, und das Ergebnis war irgendwie nicht korrekt :S :
my $Variable1="Erste Zeile aus Datei"; #Ist ein alter Timestamp --> time();
my $Variable2=time();
my $Variable3=$Variable2-$Variable1;

Das wollte er nicht, er hat irgendwas gerechnet, aber das Ergebnis stimmte nicht.

Öffne Datei
Speichere Dateiinhalt in Array-Variable
Schließe Datei

Für Dateizugriffe solltest Du generell einmal http://selfhtml.teamone.de/cgiperl/funktionen/einausgabe.htm durchlesen, da werden die relevanten Funktionen recht gut beschrieben.
Einzig das Einlesen einer Datei ist etwas 'versteckt'.

Werde ich auf jeden Fall noch machen, aber diese ausführliche Antwort von dir, hat auf jeden Fall mal eine schnelle Antwort verdient. :-)

Allerdings bin ich der Meinung, daß das Einlesen der Daten in ein Array nicht nötig ist, da Du sowieso nur den Inhalt einer bestimmten Zeile suchst.

Wie gesagt, alle Einträge die älter als 15 Minuten sind, überlesen, deshalb muss ich jede Zeile verarbeiten, zumindest jeden "Timestamp" kurz prüfen" ;-)

Hier einmal ein grobes Grundgerüst für das Einlesen:

#!/usr/bin/perl -w

use strict;
use Fcntl ':flock';

open(INFILE, "</pfad/zu/daten.datei") or die "kann Datei nicht öffnen $!";
if(flock(INFILE, LOCK_SH)) #hier wied
  {
  while(<INFILE>)
    {
    # hier gehört die Bearbeitung der Zeile, welche in der Variable $_
    # gespeichert ist, hinein.
    }
  close(INFILE);
  }
else
  {
  print "Ups, Datei konnte nicht gesperrt werden";
  }

Entschuldigt die vielleicht ganz easy Frage, ich habe leider keine Antwort auf meine Frage in SelfHTML gefunden.

Obiger Link sollte die meisten Fragen beantworten.

Und was das Auswerten der Zeilen betriff, solltest Du Dir unbedingt Funktionen wie chomp() und split() ansehen.

Ja, da war ich schon, wird schon noch...

http://selfhtml.teamone.de/cgiperl/funktionen/zeichenketten.htm
Ebenso den Unterschied zwischen numerischen (==) und textuellen (eq) Vergleichen.

Hör mir auf du! Da habe ich schon vor etwas längerer Zeit einen halben Tag lang Fehler gesucht. Aber charakter Werte werden eben mit eq verglichen, und dann funktioniert das auch. ;-)

http://selfhtml.teamone.de/cgiperl/sprache/operatoren.htm#vergleich

In COBOL geht das leicht. ;-) Leider hilft mir das hier nicht weiter...

Wenn Du COBOL schon leicht findest, dan wirst Du Staunen, wie einfahc es in Perl geht;-)

Na ja, in COBOL sieht das so aus:

Definiere Datei als E01
Definiere Datenklotz (Struktur) der genau die Länge einer Zeile der Datei hat, in meinem Fall:

01 Struktur
   05 Timestamp PIC 9(10) value zero.
   05 FILLER    PIC X(02).
   05 IP-ADR    PIC X(15).

perform until EOF = 1
   read E01 into Struktur
   at end move 1 to EOF
end-perform

Nun habe ich meine Daten sauberst in Timestamp und in IP-ADR. IP-ADR hätte ich sogar noch weiter nach unten verteilen können, mit Punkten und so, aber belassen wir es mal hierbei...

BTW.: Du weißt daß mehrere Besucher eventuell mit der selben IP-Adresse bei Dir landen können, genau so wie es innerhalb der von Dir gewählten Zeitspanne durchaus vorkommen kann, daß ein Besucher seine IP-Adresse wecheseln kann. Somit ist bei Deinem Vorhaben mit einer gewissen Unschärfe bei der Treffsicherheit zu rechnen.

Habe ich mir auch schon überlegt :S Wie groß aber ist die Wahrscheinlichkeit, dass innerhalb von 15 Minuten jemand auflegt, ein anderer sich wieder einwählt, genau des ersten Mann IP-Adresse bekommt, zufällig auf meine Homepage geht, und zufällig in mein Gästebuch schreiben möchte :S Bis diese ganzen Zufälle eintreten, ist außerdem schon wahrscheinlich so viel Zeit vergangen, dass die 15 Minuten vorbei sind.
Stell dir folgenden Zeitablauf vor:

10:00 Uhr: Er schreibt in mein Gästebuch
10:01 Uhr: Er betrachtet seinen schönen Eintrag
10:02 Uhr: Er betrachtet ihn immer noch
10:05 Uhr: Er verlässt meine Homepage
10:06 Uhr: Jetzt hat er auch die anderen 20 Browserfenster geschlossen und legt auf, nahezu zeitgleich, nämlich um
10:06 Uhr: Zweiter User wählt sich ein, bekommt die IP-Adresse des ersten Users
10:07 Uhr: Ganz zufällig gibt auch diese Uhser die URL zu meiner HP ein
10:08 Uhr: Er studiert meine HP
10:10 Uhr: Er liest Gästebucheinträge
10:11 Uhr: Er möchte auch einen GB-Eintrag schreiben :S *arg*

O.k., o.k., ich setze die Zeit auf 10 Minuten, aber das sollte dann doch passen

Ansonsten "mehrere Besucher mit der gleichen IP"!? Das ginge nur noch über ein Firmennetzwerk. Na ich will mal nicht hoffen, dass 300 Mitarbeiter zeitgleich alle in mein Gästebuch schreiben. *lol* Hilfä!!!

Wenn ein Spammer wieder auflegt und sich neu einwählt hat er die IP-Adresse gewechselt, diese Anmerkung von dir ist vollkommen korrekt. Deshalb war meine Überlegung auch schon, diese IP-Sperre mit einem Cookie zu koppeln. Aber ich habe jetzt für mich entschlossen, dass das vorerst reicht, ich werde dann sehen, ob immer noch gespammt wird, oder nicht. Aber ich denke mal, es ist zu mühselig sich ständig aus- und wieder einzuwählen.

Grüße
  Klaus

Ansonsten 1000 Dank für deine sicherlich brauchbaren Tipps und Ratschläge. Ich werde mich jetzt an die Arbeit machen. Ich bin mir sicher, dass ich es mit dieser Hilfestellung hinbekomme.

Mit freundlichen Grüßen
Sascha Müller