2016-07-12 12 views
1

Ich habe eine Datei mit ~ 10.000 Zeilen, die 2 Spalten zu ersetzen:Schneller Weg String-Paare in der Datei

org_string1 \t replacement_string1 
org_string2 \t replacement_string2 

Was ist der beste Weg (Geschwindigkeit/Bequemlichkeit) zu ersetzen all diese org_string mit ihrem entsprechenden replacement_string in eine andere Textdatei (10k Ersatz in einer zweiten Datei)?

Ich plane, sie in eine sed-Substitution-Befehl konvertieren, aber nicht sicher über die Geschwindigkeit Leistung und ob es die maximale Befehlszeilengrenze in Linux überschreiten wird.

Annahme:

  1. Alle org_string und replacement_string einzigartig sind.
  2. Der org_string ist ein einzelnes Wort (umgeben von Leerzeichen) in der Eingabedatei.
+2

Also wollen Sie 10k verschiedene Ersetzungen in einer zweiten Datei machen? Aus meiner Erfahrung wird 'sed' sehr langsam, auch wenn Sie ihm eine Datei mit 10k's/org_string1/ersatz_string1 /' Zeilen geben. Ich habe Perl oder Python nicht mit einem 10k Dictionary für reguläre Ausdrücke und Substitutionen getestet. –

+0

ich denke, es wird kein Problem sein, in Perl zu konvertieren/zu ersetzen, da Perl dies in Millisekunden tun wird. – ssr1012

+0

Der einzelne Ersatz wird schnell sein. Aber die Überprüfung jeder Zeile gegen 10k-Muster wird zusammengefasst. –

Antwort

3

Hier ist eine Technik, mit Perl, die helfen können:

my %map = (
    'the' => 'a', 
    'fox' => 'frog', 
    'jumps' => 'somersaults' 
); 

my $line = "the quick bown fox jumps over the lazy dog"; 

$line =~ s{\b(\w+)\b}{$map{$1} // $1}eg; 

say $line; 

In diesem Beispiel wird eine hartcodierte Hash-Mapping orig_strings zu replacement_strings - in Ihrem Fall, dass Sie diese Zuordnung Hash durch das Lesen der Datei von Mapping füllen würde Paare.

Dann verwendet der reguläre Ausdruck \b(\w+)\b, um jedes Wort in der Zeile zu erfassen und über $1 an die Ersatzseite zu übergeben. Da die Option /e angegeben ist, wird die rechte Seite der Ersetzung als Perl-Ausdruck behandelt, und das Ergebnis der Auswertung des Ausdrucks ist der Ersetzungstext. $map{$1} verwendet das ursprüngliche Wort als Schlüssel für den Zuordnungshash, um den Ersatztext nachzuschlagen. Der // $1 Teil sagt, wenn der Hash-Lookup undef zurückgibt (d. H. Es gibt keinen Ersatz für dieses Wort), dann verwende einfach den ursprünglichen Text.

Der \w+ Teil entspricht einer Zeichenfolge aus Wort oder Ziffer oder Unterstrich. Vielleicht möchten Sie nur alphabetische Zeichen und vielleicht Apostrophe und Bindestriche. Verwenden Sie dazu [a-zA-Z'-]+ anstelle von \w+.

Dies sollte sehr schnell sein, da es nur einen Regex über jede Zeile und nur einen Hash-Lookup für jedes Wort in jeder Zeile gibt.

+0

Dies ist viel schneller als die Mehrfachsubstitution. Vielen Dank. – Ken