Moin. Ich war mal so frei(/frech ;-) ) dein Programm unter die Lupe zu nehmen.1.) Entwickle keine Programme ohne use strict;use warnings;
2.) $muster ist nicht korrekt (quantifier * ohne Angabe darüber was 0 oder öfters Mal vorkommen soll)
3.) $muster ist als /$muster$/ schneller als /^$muster$/ weil nur das Ende des namens untersucht werden muss (bei Rekursion summieren sich solche Kleinigkeiten schnell auf)
(Tip: man könnte es bereits mit qr kompilieren. siehe http://perldoc.perl.org/perlop.html -> qr)
4.) Beim ersten open fehlt die Angabe des open-Modus
5.) Sowohl in der ersten als auch in der zweiten while-Schleife ist das close in der Schleife, statt danach, also wird dort jeweils nur ein Schleifen-Durchlauf ausgeführt (wird also nur bei Dateien mit einer einzigen Zeile funktionieren)
6.) Das zusammenfügen der Zeilen zu $daten ist sehr ineffizient. Man könnte die Zeile gleich ändern und (in eine Kopie) schreiben, damit man nicht die ganze Datei in den Speicher lädt.
7.) Das Ersetzen (s/wie/gut/) macht nicht das was Du erwartest. Es ersetzt nur das erste vorkommen von 'wie'. Es muss s/wie/gut/g heißen ( g = global-flag = ersetze ALLE vorkommen) Aber das stimmt auch noch nicht ganz; es würde immernoch z.Bsp. 'wieso' zu 'gutso' verwurschteln. Also muß es s/\bwie\b/gut/g
heißen. \b bedeutet Beginn oder Ende eines Wortes. Aber das passt immer noch nicht so ganz; es findet nur kleingeschriebene wie's. Also bräuchte es auch noch eine zweite Ersetzung für wie's mit großem W die an Satzanfängen vorkommen : s/\bwie\b/gut/g und s/\bWie\b/Gut/g; . (Natürlich fallen jetzt noch alle wie's mit falscher groß und Kleinschreibung durch [WIe, etc...] ;-D ...)
8.) Die zweite Schleife ist eigentlich überflüssig.
9.) Probier's mal so :
#!/usr/bin/perl
use strict;
use warnings;
use File::Find;
my @files;
# suchmuster
my $ist_textdatei = qr{\.txt$};
my $wie_gross = qr{\bWie\b};
my $wie_klein = qr{\bwie\b};
find(\&wanted, "/home/pasu/perltests");
sub wanted {
# wenn das Muster passt
if ( $File::Find::name =~ $ist_textdatei ) {
# Dateinamen speichern
push @files, $File::Find::name;
# Original zum LESEN öffnen
open ORIGINAL, "<", $File::Find::name
or die "Konnte '$File::Find::name' nicht zum Lesen öffnen\n($!)";
# Kopie zum SCHREIBEN öffnen
open KOPIE, ">", $File::Find::dir.'/kopie.txt'
or die $!;
# Das Original zeilenweise einlesen
while ( my $zeile = <ORIGINAL> ) {
# ALLE wie's in der gespeicherten Zeile ersetzen
$zeile =~ s/$wie_klein/gut/g;
$zeile =~ s/$wie_gross/Gut/g;
# und die veränderte Zeile gleich in die Kopie schreiben
# (so hat man nie mehr als eine Zeile im Arbeitsspeicher)
print KOPIE $zeile;
}
# NACH der Schleife beide Dateien schließen
close ORIGINAL
or die "Konnte '$File::Find::name' nicht richtig schließen\n($!)";
close KOPIE
or die "Konnte '$File::Find::dir/kopie.txt' nicht richtig schließen\n($!)";
# Das Original löschen
unlink $File::Find::name
or die "Konnte '$File::Find::name' nicht löschen\n($!)";
# und der Kopie den Namen des Originals geben
rename $File::Find::dir.'/kopie.txt', $File::Find::name
or die "Konnte '$File::Find::dir/kopie.txt' nicht umbenennen\n($!)";
}
}
Hier noch 'n paar Bücher die einem den Einstieg in Perl um einiges leichter gestalten:
http://www.oreilly.de/catalog/learnperl4ger/
http://www.oreilly.de/catalog/pperl3ger/
Datum: 05.04.2006-14:13
