[Cologne-pm] PERL - schnelles suchen & ersetzen in 100MB Datei
cem.sakaryali at easi.de
cem.sakaryali at easi.de
Wed Apr 28 06:51:34 CDT 2004
mit
s[ $matches ][ $subst_for{$&} ]xge;
geht es
Gruss
Cem
cem.sakaryali at easi.de schrieb am Wed, 28 Apr 2004 09:50:51 +0200:
> Wolfgang, Aristoteles,
>
> ich habe Probleme bei eurem Code die Umleitung in eine Datei zu machen.
>
> Wolfgang:
> print B, next unless $matches and m/$matches/;
> !!! No comma allowed after filehandle at codes.pl line 85
>
>
> Aristoteles:
> bei Dir habe ich noch ein Problem , die Erzaetzung funktioniert
> nicht richtig:)
>
> input file:
> fsdlkgjd;gjdgls1dfs;lk;ls1ksddl;fsk;s1
> fsdlkgjd;gjdgls2dfs;lk;ls2ksddl;fsk;s2
> fsdlkgjd;gjdgls3dfs;lk;ls3ksddl;fsk;s3
> fsdlkgjd;gjdgls1dfs;lk;ls1ksddl;fsk;s1
>
>
> output file:
> fsdlkgjd;gjdglsdfs;lk;lsksddl;fsk;s
> fsdlkgjd;gjdgls2dfs;lk;ls2ksddl;fsk;s2
> fsdlkgjd;gjdgls3dfs;lk;ls3ksddl;fsk;s3
> fsdlkgjd;gjdglsdfs;lk;lsksddl;fsk;s
>
>
> Danke nochmal an euch beiden
> Gruss
> Cem
>
>
> "A. Pagaltzis" <pagaltzis at gmx.de> schrieb am Wed, 28 Apr 2004 03:07:01 +0200:
> > Hallo,
> >
> > vorab an Cem: danke, dass du hin und wieder für Leben auf der
> > Liste sorgst. :-)
> >
> >
> > * Wolfgang Weisselberg <pl3rofb02 at sneakemail.com> [2004-04-27 22:32]:
> > > 1. next unless $matches; # no more matches?
> > > [...]
> > > - Du entfernst die Substitiutions. Wenn's keine mehr
> > > gibt, lohnt das Testen nicht mehr, da muss man keine
> > > leere Schleife anfahren.
> >
> > Nachdem es keine Arbeit mehr gibt, bedeutet zeilenweises Lesen
> > überflüssige Arbeit. Man will dann in einen blockorientierten
> > Modus wechseln und möglichst grosse Happen auf einmal lesen und
> > schreiben. Geht auch ohne Sysread: man setze $/ auf eine Referenz
> > auf eine Zahl, die die Blockgrösse angibt. Siehe perldoc perlvar.
> >
> > > 2. print($i), next unless m/$matches/; # and using qr//
> > > [...]
> > > - Matches sind ein seltenes Ereignis. Nicht-Matches sind
> > > haeufig. Also sollte man auf Nicht-Matches optimieren.
> >
> > Man macht (fast) nie ein m//, um zu prüfen ob ein s/// nötig ist,
> > denn s/// muss die gleiche Arbeit wie m// nochmal leisten. Man
> > macht gleich das s///, denn anhand von dessn Rückgabewert sieht
> > man, ob was passiert ist oder nicht.
> >
> > > - keine grosse Zahl an Matches mit substantiell gleichen
> > > Anfaengen (i.e. nicht Muellermeier1, Muellermeier2,
> > > Muellermeier3 ....), sonst sollte man gen_matchstrings
> > > unbedingt optimieren
> >
> > Siehe Regex::PreSuf (ja, es ist wirklich Regex:: ohne p),
> > Regexp::List.
> >
> > > open IN, $in_file or die "Cannot open $in_file: $!";
> >
> > Bitte entweder (nicht so toll)
> >
> > open IN, "<$in_file"
> >
> > oder (besser)
> >
> > open IN, '<', $in_file
> >
> > Aber nicht ohne Modus schreiben -- sonst wird man irgendwann
> > durch seltsame Dateinamen vom magic open überrascht. Erstere Form
> > kommt übrigens nicht mit Dateinamen zurecht, die mit Leerzeichen
> > anfangen.
> >
> > Siehe "Two-arg open() considered dangerous",
> > <http://www.perlmonks.org/index.pl?node_id=131085>
> >
> > Darüber, ob man Package-Filehandles verwenden sollte, kann man
> > auch streiten. Ich nehme lieber grundsätzlich lexikalische
> > Variablen, also
> >
> > open my $fh, '<', $in_file
> >
> > > sub gen_matchstrings { # where is map for hashes??
> > > my $in = shift;
> > > my $string = join( '|', keys %$in );
> > > return qr/$string/; # precompile regexp
> > > }
> >
> > Vorsicht! Du willst
> >
> > my $string = join( '|', map quotemeta, keys %$in );
> >
> > Sonst spielen zufällig vorhandene Metazeichen in der Eingabe ihre
> > Streiche mit dir.
> >
> > > foreach my $from ( keys %$replaces_href ) {
> > > next unless /$from/;
> > > s/$from/$$replaces_href{$from}/g;
> > > delete $$replaces_href{$from};
> > > }
> >
> > Ganz schön umständlich und ineffizient.
> >
> > s/// muss für jedes $from das Pattern neu kompilieren.
> >
> > Ausserdem wieder die gleiche Falle mit Metazeichen in der
> > Eingabe; es sollte C<s/\Q$from/.../> sein.
> >
> > Besser geht es, wenn du den vorher kompilierten Regex mit
> > Klammern versiehst, dann kann er hier zum Matchen verwendet
> > werden, wobei $1 die Ersetzung auswählt. Die explizite Schleife
> > wird mit Hilfe von /e dann ganz überflüssig.
> >
> >
> > So sieht summa summarum meine Fassung aus:
> >
> > #!/usr/bin/perl
> > use strict;
> > use warnings;
> >
> > sub rx_from_list { map qr/($_)/, join '|', map quotemeta, @_ }
> >
> > my %subst_for = (
> > 's1' => 'e1',
> > 's2' => 'e2',
> > 's3' => 'e3',
> > 's4' => 'e4',
> > );
> >
> > my $matches = rx_from_list keys %subst_for;
> >
> > open my $fh, '<', $filename
> > or die "Cannot open $filename: $!";
> >
> > while (<$fh>) {
> > my %found;
> > s[ $matches ][ $found{$1}++; "$subst_for{$1}"; ]xge;
> > print;
> >
> > if(%found) {
> > delete @subst_for{ keys %found };
> >
> > # ultrashortcircuit if no work left
> > unless ( %subst_for ) {
> > local $/ = \262144; # read 256kb chunks
> > print while <$fh>;
> > last;
> > }
> >
> > $matches = rx_from_list keys %subst_for;
> > };
> >
> > }
> >
> > --
> > Gruss,
> > Aristoteles
> >
> > "Wer nicht über sich selbst lachen kann, nimmt das Leben nicht ernst genug."
> > _______________________________________________
> > Cologne-pm mailing list
> > Cologne-pm at mail.pm.org
> > http://mail.pm.org/mailman/listinfo/cologne-pm
>
>
>
> --
> | __| / _ \ / __|(_) | C e m S a k a r y a l i
> | _| | _ |\__ \| | | Eupener Str. 159, Geb. 107
> |___||_| |_||___/|_| | D-50933 Koeln GERMANY
> Engineering GmbH | Tel: +49 221/650 496 12 Fax: 22
> http://www.easi.de | mailto:cem.sakaryali at easi.de
>
> _______________________________________________
> Cologne-pm mailing list
> Cologne-pm at mail.pm.org
> http://mail.pm.org/mailman/listinfo/cologne-pm
--
| __| / _ \ / __|(_) | C e m S a k a r y a l i
| _| | _ |\__ \| | | Eupener Str. 159, Geb. 107
|___||_| |_||___/|_| | D-50933 Koeln GERMANY
Engineering GmbH | Tel: +49 221/650 496 12 Fax: 22
http://www.easi.de | mailto:cem.sakaryali at easi.de
More information about the Cologne-pm
mailing list