[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