Was ist ein guter Weg, um Zeichenfolgen in einer Datei mit einem Wörterbuch mit viel zu ersetzen von Substituend-Substituent-Paaren? Und um viel , ich meine eigentlich etwa 20 – nicht viel, aber so viele, dass ich sie ordentlich organisieren möchte.
Ich möchte alle Substituenten-Substituenten-Paare in einer Datei dictionary.txt
sammeln auf eine einfach zu handhabende Weise, da ich viele Sachen ersetzen muss, sagen Sie so:
"yes" : "no"
"stop" : "go, go, go!"
"wee-ooo" : "ooooh nooo!"
"gooodbye" : "hello"
"high" : "low"
"why?" : "i don't know"
Jetzt möchte ich diese Ersetzungen in einer Datei novel.txt
anwenden .
Dann möchte ich magiccommand --magicflags dictionary.txt novel.txt
ausführen sodass alle Instanzen von yes
in novel.txt
werden durch no
ersetzt (also sogar Bayesian
würde durch Banoian
ersetzt werden ) und alle Instanzen von goodbye
in novel.txt
würde durch hello
ersetzt werden und so weiter.
Bisher müssen die Zeichenfolgen, die ich ersetzen (und durch) ersetzen muss, nicht Anführungszeichen (weder einfach noch doppelt) enthalten. (Es wäre jedoch schön, eine Lösung zu sehen, die gut mit Zeichenfolgen funktioniert, die natürlich Anführungszeichen enthalten.)
Ich kenne sed
und awk
/ gawk
können solche Sachen grundsätzlich, aber können sie auch mit solchen Wörterbuchdateien arbeiten? Sieht aus wie gawk
wäre der richtige Kandidat für magiccommand
, was sind die richtigen magicflags
? Wie muss ich meine dictionary.txt
formatieren? ?
Akzeptierte Antwort:
Hier ist eine Möglichkeit mit sed
:
sed '
s|"(.*)"[[:blank:]]*:[[:blank:]]*"(.*)"|1
2|
h
s|.*n||
s|[&/]|\&|g
x
s|n.*||
s|[[.*^$/]|\&|g
G
s|(.*)n(.*)|s/1/2/g|
' dictionary.txt | sed -f - novel.txt
Wie es funktioniert:
Der 1. sed
verwandelt sich in dictionary.txt
in eine Skriptdatei (Bearbeitungsbefehle, einer pro Zeile). Dies wird zum 2. sed
geleitet (beachten Sie die -f -
was bedeutet, dass Befehle von stdin
gelesen werden ), der diese Befehle ausführt und novel.txt
bearbeitet .
Dazu muss Ihr Format übersetzt werden
"STRING" : "REPLACEMENT"
in einen sed
Befehl und Escapezeichen für alle Sonderzeichen im Prozess für beide LHS
und RHS
:
s/ESCAPED_STRING/ESCAPED_REPLACEMENT/g
Also die erste Substitution
s|"(.*)"[[:blank:]]*:[[:blank:]]*"(.*)"|1
2|
verwandelt "STRING" : "REPLACEMENT"
in STRINGnREPLACEMENT
(n
ist ein Newline-Zeichen). Das Ergebnis wird dann über das h
kopiert altes Leerzeichen.s|.*n||
löscht den ersten Teil und behält nur REPLACEMENT
dann s|[&/]|\&|g
maskiert die reservierten Zeichen (das ist der RHS
).
Es ist dann ex
ändert den Haltepuffer mit dem Muster space und s|n.*||
löscht den zweiten Teil und behält nur STRING
und s|[[.*^$/]|\&|g
übernimmt die Flucht (das ist die LHS
).
Der Inhalt des Haltepuffers wird dann über G
an den Musterbereich angehängt Der Inhalt des Musterbereichs ist jetzt also ESCAPED_STRINGnESCAPED_REPLACEMENT
.
Die endgültige Auswechslung
s|(.*)n(.*)|s/1/2/g|
wandelt es in s/ESCAPED_STRING/ESCAPED_REPLACEMENT/g
um