AW: Projekt: imdb -sackgasse?

Thomas Berger ThB at gymel.com
Mi Feb 12 22:34:41 CET 2003


Lieber Herr Lehmann,

> autsch. ja, das kommt davon, wenn man perl nicht versteht (ich hatte ihre perl-zeile SO verstanden, daß sie
> die TABS reduziert...). aber das ist eine ebene, wo ich mental nicht mitkommen.
> 
> also die zeile
> 
> "while ($input=~ s/(\n[^\t\n]+)(\t.*)\n\t+/$1$2$1\t/) {};"
> macht das, was da oben steht?

ja. Herrn Fischers Zeile funktioniert wie versprochen.

> räusper: wie kann ich diese perl-zeile entschlüsseln? haben sie lust (und zeit), allen anderen (da gibts es
> bestimmt einige mächtig interessierte kollegen) es mal zu erklären.... untertänigst nachfragend.... ;-)

Lieber nicht: sie setzt voraus, dass die gesamte Datei in 
eine Variable eingelesen ist und arbeitet sich dann Tab
fuer Tab mit jeweils umspeichern durch die Datei. Das
ist bei einer 14MB-Datei mit 370000 Einzeleintraegen
vielleicht nicht soo empfehlenswert.

Wegen der Paedagogik hier also ein Ansatz, der nicht 
ganz so "dirty" ist, allerdings auch kein Einzeiler:

#!perl -w
use strict;
my $merker;     # $merker wird gefundene Namen aufbewahren
while ( <> ) {
        # "Anfangszeilen" der Form: Text Tab(s) Text
        # \t ist Tab, [^\t] alles ausser Tab
   if ( /^(\S\S[^\t]+)\t+(.*)/ ) {
       $merker = $1;
       print "$merker\t$2\n";
     }
        # "Fortsetzungszeilen" der Form: Tab(s) Text
   elsif ( /^\t\t+(.*)/ ) {
       print "$merker\t$1\n";
     }
        # Sonstige Zeilen sind leer oder Kommentare
  }


Versuch mit der Idee von Herrn Fischer, allerdings so modifiziert,
dass sie immer nur einen Absatz (Zeilengruppe, durch Doppeltes
Zeilenende abgeschlossen) auf einmal bearbeitet, nicht die
gesamte Datei: 

#!perl -w
use strict;
$/ = "";    # im folgenden absatzweise einlesen
while ( <> ) {   # Fuer jeden "Absatz"
    while (  # ersetze solange ersetzbar ist. Naemlich:
           s/^([^\t]+)            # Anfang des Absatzes
              \t+(.*)             # Tabs(+) plus egal
              \n\t+([^\n]+)       # Zeile, die mit Tab begint
             /$1\t$2\n$1\t$3/sx   # durch
        # Anfang Mitte Anfang Rest
           ) { # nur ersetzen, nichts weiter tun
      }
    print;     # Ueberarbeitete Zeilengruppe ausgeben
  }

Im Gegensatz zur ersten Loesung laesst sie allerding den Dateikopf (bloed) 
und die Durchschuesse (egal) stehen und das Laufzeitverhalten ist
eher maessig.
Sie laesst sich allerdings auch als Einzeiler ausdruecken:

perl -000 -p -e "{} while s/^([^\t]+)\t+(.*)\n\t+([^\n]+)/$1\t$2\n$1\t$3/s" producers_list > prod.tab

viele Gruesse
Thomas Berger




Mehr Informationen über die Mailingliste Allegro