[Cologne-pm] PERL - schnelles suchen & ersetzen in 100MB Datei

cem.sakaryali at easi.de cem.sakaryali at easi.de
Wed Apr 28 02:50:51 CDT 2004


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




More information about the Cologne-pm mailing list