#!/usr/bin/perl use strict; # Speicherverbrauch < 100 M mit sample4.txt. # Laufzeit < 10s auf Intel(R) Pentium(R) 4 CPU 2.60GHz. # Perlcode in Kompaktform < 20 Zeilen. # Ersten Parameter @ARGV[0] als Dateiname interpretieren und Datei oeffnen. # Abbruch, wenn Datei nicht geoeffnet werden kann. open(IN, @ARGV[0]) or die "Cannot open file '@ARGV[0]': $!\n"; # Gesamte Datei in eine Stringvariable ins RAM lesen, indem Variable $/ (Input # Record Separator) auf undefiniert gesetzt wird. undef $/; my $file = ; # Nach Fussnoten-Trenner @footnote suchen, Abbruch wenn nicht auffindbar. # Wichtig: durch den Zusatz 'g' wird bei der naechsten Suche in $file im # Anschluss an diese Fundstelle pos($file) weitergesucht. $file =~ /\@footnote/g or die 'Missing marker "@footnote".', "\n"; # $notecount: Anzahl der Fussnotentexte im Verweisteil am Textende. # @indexmap: Abbildung alte Fussnotennummer auf neue aufsteigende Nummer. # Leichter lesbar als (my $notecount = 0; my @indexmap) = (0, ()); my $notecount = 0; my @indexmap = (); # Alle Fussnotennummern am Textende suchen und als Index im Array @indexmap # verwenden. Der dem Index zugeordnete Wert ist der aufsteigende Zaehler # $notecount. Sortierung nicht erforderlich! Beachten: durch die vorherige # Suche /\@footnote/g wird nur im Verweisteil am Textende gesucht. Durch 'g' # wird immer das naechste Vorkommnis gefunden. Mit leichter lesbarer # Darstellung der Schleife: while ($file =~ /\[(\d+)\]/g) { $notecount = $notecount + 1; $indexmap[$1] = $notecount } # Nun Suchposition auf Anfang der Datei $file im Speicher zuruecksetzen. pos($file) = 0; # $from zeigt in $file immer auf die Position nach der letzten gefundenen # Fussnotenkennung [n], zu Beginn 0. my $from = 0; # Alle Fussnotenkennungen der Reihe nach absuchen. while ($file =~ /\[(\d+)\]/g) { # Alle Zeichen nach der letzten Fussnotenkennung bis vor die aktuelle # ausgeben. $1 enthaelt als Suchergebnis die Zahl zwischen '[' und ']'. # Subtraktion von 2 beruecksichtigt '[' und ']'. print substr($file, $from, pos($file) - length($1) - 2 - $from); # Die Fussnotenkennung ausgeben, wobei die alte Nummer durch die neu # zugewiesene aus dem Array @indexmap ersetzt wird. print '[' . $indexmap[$1] . ']'; # Die Position noch nicht ausgegebenen Textes nachziehen. $from = pos($file); } # Resttext ausgeben. print substr($file, $from);