PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Suche Hilfescript (Perl)



ALINA1981
13.12.2005, 07:27
Hallo Freunde

Kennt jemand von euch ein gutes Script was ich vorab als Hilfe nehmen könnte um ein Programm in Perl zu schreiben was folgendes kann. Programmiere diese Sprache noch nicht sehr lange.
Ich möchte in einem Ordner welche Textdateien enthält nach und nach alle Inhalte abarbeiten die eine bestimmte Endung haben. Dort möchte ich mir den Absender aus der Datei rausfiltern und diese Textdatei nach Absender in einen separaten dafür vorgesehenen Ordner verschieben. Wenn es den Ordner schon gibt will ich die Datei einfach verschieben. Wenn es sie noch nicht gibt soll ein neuer Ordner erzeugt und dann die Textdatei hineingeschoben werden. Wenn alle Dateien abgearbeitet sind soll er aufhören.

Ich bin sicher, daß es für euch kein Problem darstellt. Ich bin da noch etwas ungeübt und brauche die Hilfestellung dafür.

Gibt es dafür überhaupt ein Hilfescript was man umschreiben könnte oder muß ich von Anfang beginnen?

Danke euch vorab
Alina :headup:

lordlamer
13.12.2005, 08:08
hi

du solltest das script von grund auf selber basteln.

guck dir mal pronix.linuxdelta.de an. dort gibts nen tutorial zu perl.

dort solltest du dir auf jedenfall raussuchen wie man verzeichnisse durchsucht, dateienöffnet und durchsucht.

und dann baust du dein script so langsam von alleine zusammen. hat den vorteil das du richtig was lernst.

mfg frank

Xanti
13.12.2005, 09:14
Hallo Alina,

ich bin ebenfalls der Meinung von lordlamer. Suche Dir Tutorials im Netz, borg Dir Bücher aus der lokalen (Uni-)Bibo und schreib das Programm, indem Du Dir kleine Ziele setzt. Z.B. zuerst Verzeichnis lesen, dann Files parsen ...

Wenn Du dann noch Detailfragen hast, kannst Du sie gerne hier stellen :)

Gruss, Phorus

ALINA1981
13.12.2005, 10:04
Hallo Freunde.

alles klar, werde ich versuchen.
Habe nur das Problem, dass ich nächsten Dienstag fertig sein muß.

Das heisst dann wohl Nachtschicht schieben....:( .

Kann man wohl nichts machen.
Aber danke trotzdem.

Alina

lordlamer
13.12.2005, 10:26
hier ne kleine hilfe von pronix.linuxdelta.de

--------------------

Hierzu ein Skript, womit das aktuelle Verzeichnis ausgelesen wird ...


#!/usr/bin/perl -w

opendir(DH, ".") or die "Fehler bei opendir : $!\n";
while(defined($name=readdir(DH))){
print $name , "\n";
}
closedir DH;


Wenn Sie nun z.B. nach Textdateien in Ihrem Verzeichnis suchen, brauchen Sie nur den Pattern-Matching-Operator verwenden ...


#!/usr/bin/perl -w

opendir(DH, ".") or die "Fehler bei opendir : $!\n";
while(defined($_=readdir(DH))){
print $_ , "\n" if $_=~m/.*\.txt/;
}
closedir DH;

Für Verzeichnisse erstellen
http://pronix.linuxdelta.de/Perl_cgi/Perl/perl_kurs_kapitel13b.shtml#13_11

Mit dem folgendem Skript können Sie aus einer Datei lesen ...


#!/usr/bin/perl -w

print "Welche Datei wollen Sie zum Lesen öffenen : " ;
chomp ( $file=<>);

open(FH, "< $file")
or
die "\nKonnte die Datei $file nicht zum Lesen öffnen\n";

while($zeile=<FH>){
if($. %10){ #Alle 10 Zeilen anhalten
print $zeile;
}
else{
print "Für weiteren Text bitte drücken\n";
<STDIN>;
}
}
close(FH);

-----------------

Ich denke das sollte dir erstmal helfen. Damit kannste eigentlich schon so gut wie alles machen. Du musst nur noch die Zeile beim auslesen der Datei Prüfen.

Mfg Frank

Wolfgang
13.12.2005, 10:34
Hallo Freunde.

alles klar, werde ich versuchen.
Habe nur das Problem, dass ich nächsten Dienstag fertig sein muß.

Das heisst dann wohl Nachtschicht schieben....:( .

Kann man wohl nichts machen.
Aber danke trotzdem.

Alina

Hallo
Noch ein paar Tipps zum Beschleunigen.

Konzentriere deine Arbeit auf RegExp.
Versuche gerade am Anfang nicht alles mit einer RegExp zu erschlagen, das sieht zwar cool aus, ist aber meist für Anfänger sehr ungeeignet um unvermeindliche Fehler zu lokalisieren.
Schau dir das Modul File::Find an, da sind in der Docu einige Beispiele.
Schau dir an, wie Parameter übergeben werden.

Ganz kurzes Beispiel Skelett.


#!/usr/bin/perl -w
use strict;
use File::Find;
my $filematch="suchpattern"; # was im Dateinamen vorkommen (Dateifilter)
die "Use $0 Path\n" unless $ARGV[0];
my $dir=$ARGV[0];
find ( sub{
return unless /$filematch/; #zurück wenn Dateiname nicht matcht
my $f=$_; #sichern wegen return
#hier mehr Code was alles gemacht werden soll
#eg. open IN, "<$_" ||die "error $!"; ...
#am Ende $_ zurückgeben! wichtig!
return $f;
}, $dir);



Du kannst natürlich statt sub{...} auch eine Referenz auf eine Funktion schreiben.
Ich bin da leider perl- Konsolen verseucht. :D
HTH
Gruß Wolfgang

ALINA1981
16.12.2005, 08:37
Guten morgen allen,

Mein Programm läuft soweit ganz brauchbar. (Und sorry Wolfgang, hab doch ein bischen viel RegExp verwendet). ;-)
Eine detaillierte Frage hätte ich dann aber doch noch.
Ich habe einen Ordner voller TXT und anderen dateien. Dieser befindet sich im Ordner Perl/Dateteien/ . Was muss ich eingeben, damit er mir den Ordner von oben nach unten ausließt und mir speziell die txt dateien aufmacht, diese nach dem wort test durchsucht und wenn test vorhanden diese aus dem Dateienordner in den Perl/OUT Ordner verschiebt?
Ich habe oben schon einige Beispiele, aber irgendwie kann ich das nicht auf mein Programm umstricken. Ausserdem ist das alles etwas lang und kompliziert geworden.

Kann mir da jemand helfen und mir das in einem kürzeren Skript zeigen.

Danke
Alina

Wolfgang
16.12.2005, 13:57
Guten morgen allen,

Mein Programm läuft soweit ganz brauchbar. (Und sorry Wolfgang, hab doch ein bischen viel RegExp verwendet). ;-)
Eine detaillierte Frage hätte ich dann aber doch noch.
Ich habe einen Ordner voller TXT und anderen dateien. Dieser befindet sich im Ordner Perl/Dateteien/ . Was muss ich eingeben, damit er mir den Ordner von oben nach unten ausließt und mir speziell die txt dateien aufmacht, diese nach dem wort test durchsucht und wenn test vorhanden diese aus dem Dateienordner in den Perl/OUT Ordner verschiebt?
Ich habe oben schon einige Beispiele, aber irgendwie kann ich das nicht auf mein Programm umstricken. Ausserdem ist das alles etwas lang und kompliziert geworden.

Kann mir da jemand helfen und mir das in einem kürzeren Skript zeigen.

Danke
Alina

Also so schnell aus der Hüfte:

#!/usr/bin/perl -w
use strict;
use File::Find;
use File::Copy;
my $dest="/Perl/OUT/";
my $source="/Perl/Dateteien/";

find(\&want,$source);
print "All down\n";

sub want {
#zurück wenn Datei nicht auf txt endet oder keine Datei ist
# Schreibe es hier der Übersicht halber als zwei einzelne Befehle ;)
return unless -f $_; #nur Dateien

# Dateien mit . (eg .htaccess .sshkey) und
#Verzeinträge übergehen

return if /^\./;
return unless (/txt$/ig);#matcht auf txt am Ende des Filename

my $file=$_; #sichern für Returnwert, find braucht das
# oeffnen und suchen
open IN, "<$_"||die "error by read $_ msg $!";
while (<IN>){
next unless (/testtext/); #matcht nicht-> nächste Zeile
#hier landen wir wenn etwas gefunden wurde
# kopieren und Filehandle close
close IN;
my $old=$File::Find::name;
my $new ="$dest"."$file";
copy $old, $new;
last; # Bedingung erfüllt raus
}#end while
close IN; #falls nix gefunden wurde sonst gibbet es Error bein nächsten Oeffnen ;)
return $file;
}#end func want


Wie gesagt nicht getestet und wenn du Fehler findest darfst du die korrigieren. ;)
Anpassen musst du das selber z.B. Suchtesxt etc.

Ein Paar Zeilen deines Versuches würde ich aber gerne sehen.

Gruß Wolfgang

Edit//Doch ein Fiptehler gefunden ;)

ALINA1981
18.12.2005, 14:20
Danke Wolfgang

Was du mal so eben aus der Hüfte gezaubert hast, hat mir locker 2 Stunden Verständnisprobleme verursacht. Nach zahlreichen Lektüren kann ich dir nun folgen. Aber jetzt läuft es echt gut. Habe es etwas auf mich umgeschrieben.

Frage, wie kann ich zu deinem Script noch etwas einbauen um eine Variable ($datei) des dateinamens (ohne .txt) der Verschobenen datei zu bekommen. Muß mit diesem nämlich noch weiterarbeiten.

Danke
Alina

Xanti
18.12.2005, 14:37
Wenn der neue File-Name in $new gespeichert ist (falls ich Wolfgangs Skript richtig überflogen habe), kommst Du mit folgendem weiter:



$datei = $new;
$datei =~ s/\.txt$//i;


Gruss, Phorus

Wolfgang
18.12.2005, 17:22
Hallo Alina



Danke Wolfgang

Was du mal so eben aus der Hüfte gezaubert hast, hat mir locker 2 Stunden Verständnisprobleme verursacht. Nach zahlreichen Lektüren kann ich dir nun folgen. Aber jetzt läuft es echt gut. Habe es etwas auf mich umgeschrieben.

Dabei habe ich extra viele Kommentare eingebaut.
Normalerweise ist das mit viel weniger Code machbar. ;)
Hauptsache du hast es hinbekommen.



Frage, wie kann ich zu deinem Script noch etwas einbauen um eine Variable ($datei) des dateinamens (ohne .txt) der Verschobenen datei zu bekommen. Muß mit diesem nämlich noch weiterarbeiten.

Danke
Alina

Ich verschiebe in meinem Beispiel aber keine Datei, sondern kopiere diese nur, wenn die Bedingung zutrifft.
Der einfache Dateiname steht in $_ bzw bei mir auch nochmal in $file.
Wie daraus den Namen ohne den letzten drei Chars nach dem letzten Punkt (unter M$ auch Dateierweiterung genannt) bekommst, hat Phorus schon beschrieben.
Seine Variante funktioniert auch im Falle des vollen Pfades, weil der non-greedy Mode default auf false steht.

Du könntest diese also einfach in einem Array sammeln.
Einfach am Anfang ein Array definieren:
my @duplicat;
und dann hinter dem Kopieren ein
push @duplicat,$file

und am Ende mit:

print join '\n',map{$_=~s/\..*$//g} sort @duplicat;
ausgeben

Gruß Wolfgang

Xanti
18.12.2005, 17:45
Nu aber flink, Alina. Nur noch zwei Tage Zeit ;)

ALINA1981
23.12.2005, 09:03
Hallo Wolfgang & Phorus,

Hab das Programm hinbekommen. Es läuft echt gut. Hätte etwas kürzer sein können aber das spielt für mich momentan noch keine Rolle. Bekomme Anfang des Jahres von der Firma dafür eine Schulung spendiert und werde das wohl dann etwas öfter machen. Ist neben meiner Hauptarbeit nun mein Zweitprojekt. Das heisst, dass ich euch wohl noch öfter mit einigen Fragen belästigen werde wenn ich dann Nachts davor hocke. :-). Falls ihr dann noch Lust habt, könnt ihr ja ab und zu mal drauf Antworten. Also, wie gesagt. Danke nochmal.

Alina

Havoc][
23.12.2005, 09:18
Wenn es OpenSource ist kannst du ja mal pasten wie du es nun hinbekommen hast ;).

Aber gut zu wissen das es funktioniert hat. So eine Rückmeldung bekommt man von den wenigsten Usern. Ich denke das motiviert jeden Moderator, wenn er weiss das er Helfen konnte *g*.

Havoc][