Was ist ein guter Weg, um Zeichenfolgen in einer Datei mithilfe eines Wörterbuchs mit vielen Substituenten-Substituenten-Paaren zu ersetzen? Und mit viel meine ich eigentlich ungefähr 20 - nicht viel, aber viel genug, um sie ordentlich zu organisieren.
Ich möchte irgendwie alle Substituenten-Substituenten-Paare in einer Datei dictionary.txt
auf einfach zu verwaltende Weise sammeln , da ich viele Dinge ersetzen muss, sagen wir:
"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 anwenden novel.txt
.
Dann möchte ich ausführen, magiccommand --magicflags dictionary.txt novel.txt
damit alle Instanzen von yes
in novel.txt
durch ersetzt werden no
(also Bayesian
würde sogar durch ersetzt werden Banoian
) und alle Instanzen von goodbye
in novel.txt
durch ersetzt werden hello
und so weiter.
Bisher sind die Saiten , die ich brauche zu ersetzen (und ersetzen) noch nicht haben keine Anführungszeichen (weder einzelne noch doppelt) in ihnen. (Es wäre jedoch schön zu sehen, dass eine Lösung natürlich gut mit Zeichenfolgen funktioniert, die Anführungszeichen enthalten.)
Ich kenne sed
und awk
/ oder gawk
kann solche Sachen hauptsächlich machen, aber können sie auch mit solchen Wörterbuchdateien arbeiten? Scheint, als gawk
wäre der richtige Kandidat für magiccommand
, was sind die richtigen magicflags
? Wie muss ich meine formatieren dictionary.txt
?
quelle
Antworten:
Hier ist ein Weg mit
sed
:So funktioniert es:
Die erste
sed
wirddictionary.txt
zu einer Skriptdatei (Bearbeitungsbefehle, einer pro Zeile). Dies wird an die 2. weitergeleitetsed
(beachten Sie,-f -
was bedeutet, dass Befehle von gelesen werdenstdin
), die diese Befehle ausführt und bearbeitetnovel.txt
.Dies erfordert die Übersetzung Ihres Formats
in einen
sed
Befehl und das Entkommen von Sonderzeichen im Prozess für beideLHS
undRHS
:Also die erste Auswechslung
wird
"STRING" : "REPLACEMENT"
zuSTRING\nREPLACEMENT
(\n
ist ein Zeilenumbruchzeichen). Das Ergebnis wird dann über denh
alten Raum kopiert .s|.*\n||
löscht der erste Teil keeping nurREPLACEMENT
danns|[\&/]|\\&|g
die reservierten Zeichen entweicht (das ist dieRHS
).Es
x
ändert dann den Haltepuffer mit dem Musterraum unds|\n.*||
löscht nur den zweiten Teil, der beibehalten wird,STRING
unds|[[\.*^$/]|\\&|g
führt die Escape-Aktion aus (dies ist derLHS
).Der Inhalt des Haltepuffers wird dann über an den Musterraum angehängt,
G
so dass nun der Inhalt des Musterraums istESCAPED_STRING\nESCAPED_REPLACEMENT
.Die endgültige Auswechslung
verwandelt es in
s/ESCAPED_STRING/ESCAPED_REPLACEMENT/g
quelle
Hier ist eine Perl-Version. Es erstellt einen Hash mit vorkompilierten regulären Ausdrücken und durchläuft dann jede Eingabezeile, wobei alle regulären Ausdrücke auf jede Zeile angewendet werden.
perl
's-i
wird für die "In-Place-Bearbeitung" der Eingabedatei verwendet. Sie können problemlos reguläre Ausdrücke oder Ersatzzeichenfolgen hinzufügen oder ändern.Das Vorkompilieren der regulären Ausdrücke mithilfe von
qr//
verbessert die Geschwindigkeit des Skripts erheblich. Dies macht sich besonders bemerkbar, wenn viele reguläre Ausdrücke und / oder viele Eingabezeilen verarbeitet werden müssen.Hier ist eine andere Version, die das Wörterbuch vom ersten Dateinamen in der Befehlszeile einliest, während der zweite (und optionale nachfolgende) Dateinamen noch verarbeitet wird:
quelle
Ich habe angefangen, dies als Kommentar zu schreiben, aber es wurde zu kompliziert, daher eine zweite Perl-Antwort. In Anbetracht Ihrer Quelldatei können Sie einen ordentlichen Perl-Trick verwenden, um einen regulären Ausdruck zu erstellen:
Wir generieren einen Hash mithilfe einer mehrzeiligen Musterübereinstimmung und
map
erstellen Schlüsselwertpaare.Wir erstellen einen Such-Regex und verwenden die darin erfassten Werte, um ihn zu ersetzen.
Verwenden
<>
ist das magische Dateihandle von Perl -STDIN
oder Dateien, die in der Befehlszeile angegeben sind. Viel wie sed macht es. (Sie können eine Datei verwenden und sie 'normal' für das Muster lesen. Die Verwendung vonDATA
dient nur zur Veranschaulichung.)quelle