2016-11-11 3 views
0

Ich habe ein Wörterbuch dict mit Aufzeichnungen getrennt durch Ersetzen „:“ und Datenfelder durch neue Linien, zum Beispiel:gsub für Übersetzungen nicht funktionieren

:one 
1 
:two 
2 
:three 
3 
:four 
4 

Jetzt mag ich awk alle Vorkommen jeden Datensatz ersetzen in die input Datei, zB

onetwotwotwoone 
two 
threetwoone 
four 

Mein erstes awk Skript sah wie folgt aus und funktioniert gut:

BEGIN { RS = ":" ; FS = "\n"} 
NR == FNR { 
rep[$1] = $2 
next 
} 
{ 
for (key in rep) 
grub(key,rep[key]) 
print 
} 

mir geben:

12221 
2 
321 
4 

leider eine andere dict Datei durch reguläre Ausdrücke verwendet, um einige Zeichen enthält, so habe ich ersetzen Zeichen in meinem Skript zu entkommen. Durch Verschieben von Schlüssel und rep [key] in eine Zeichenfolge (die dann für Escape-Zeichen analysiert werden kann), ersetzt das Skript nur den zweiten Datensatz im dict. Warum? Und wie zu lösen?

Hier ist der aktuelle zweite Teil des Skripts:

{ 
for (key in rep) 
orig=key 
trans=rep[key] 
gsub(/[\]\[^$.*?+{}\\()|]/, "\\\\&", orig) 
gsub(orig,trans) 
print 
} 

Alle Skripte von awk -f translate.awk dict input

Vielen Dank im Voraus ausgeführt werden!

Antwort

1

Ihr grundlegendes Problem ist die Verwendung von Zeichenfolgen in Regexp- und Rückverweiskontexten, wenn Sie sie nicht möchten und dann versuchen, die Metazeichen in Ihren Zeichenfolgen zu deaktivieren, die Zeichen, die Sie aktivieren, indem Sie sie in diesen Kontexten verwenden. Wenn Sie Zeichenfolgen verwenden möchten, verwenden Sie sie in Zeichenfolgenkontexten, das ist alles.

Sie dies nicht wollen:

gsub(regexp,backreference-enabled-string) 

Sie wollen etwas mehr wie folgt aus:

index(...,string) substr(string) 

Ich denke, das ist, was Sie zu tun versuchen:

$ cat tst.awk 
BEGIN { FS = ":" } 
NR == FNR { 
    if (NR%2) { 
     key = $2 
    } 
    else { 
     rep[key] = $0 
    } 
    next 
} 
{ 
    for (key in rep) { 
     head = "" 
     tail = $0 
     while (start = index(tail,key)) { 
      head = head substr(tail,1,start-1) rep[key] 
      tail = substr(tail,start+length(key)) 
     } 
     $0 = head tail 
    } 
    print 
} 

$ awk -f tst.awk dict file 
12221 
2 
321 
4 
0

Niemals etwas fragen .... Nur ein paar fehlende Klammern ...?!

{ 
for (key in rep) 
{ 
orig=key 
trans=rep[key] 
gsub(/[\]\[^$.*?+{}\\()|]/, "\\\\&", orig) 
gsub(orig,trans) 
} 
print 
} 

funktioniert wie ein Charme.

+0

Sie verwandeln Strings in Regexps, indem Sie sie in einem Kontext verwenden, der nur auf Regexps funktioniert (das erste Argument für gsub()), aber versuchen, das Regexp-Metachara zu deaktivieren cters in den Strings, so dass sie sich nicht wie Regexps verhalten, wenn sie in diesem Regexp-Kontext verwendet werden. Scheint dir nicht ein bisschen verschlungen zu sein? –