Ich möchte alle Vorkommen eines Wortes verwenden sed
oder perl
ersetzen, das kein bestimmtes Wort vor sich hat.
Zum Beispiel habe ich eine Textdatei, die eine Handlung eines Films enthält, und ich möchte alle Vorkommen des Nachnamens eines Charakters durch seinen Vornamen ersetzen, aber nur, wenn sein Vorname nicht unmittelbar vor seinem Nachnamen steht.
Der Beispieltext könnte folgendermaßen aussehen:
John Smith and Jane Johnson talk about Smith's car.
Ich möchte, dass es so aussieht:
John Smith and Jane Johnson talk about John's car.
Wenn ich es nur tue sed 's/Smith/John/' file
, hätte ich:
John John and Jane Johnson talk about John's car.
Der Vorname, der vor dem Nachnamen steht, ist immer der gleiche. Ich muss mich nicht mit John Smith
und befassen Frank Smith
. Ich brauche nur einen passenden Weg, Smith
dem es nicht John
vorausgeht.
sed
regular-expression
perl
jonescb
quelle
quelle
Antworten:
Wäre einfach mit jeder Sprache, in der die regulären Ausdrücke in der Lage sind, sich zu verhalten. Natürlich ist Perl der erste auf der Liste:
Die Schwachstelle besteht darin, dass zwischen „John“ und „Smith“ mehr als ein Nicht-Wort-Zeichen steht. Leider würde ein Quantifizierer wie
+
for\W
den Fehler "Lookbehind nicht implementiert" mit variabler Länge auslösen.quelle
EDIT .. re your comment .. Hier ist ein neues Skript, das sich nicht um (z. B.) William Smith kümmert. Es verschleiert vorübergehend Muster, die es als Smith beibehält (unverändert).
Wenn Sie sich Sorgen um Herrn, Herrn, Frau machen, dann funktioniert das.
Sie können für William sorgen, indem Sie seinen Namen zur Liste oder hinzufügen , z.
sed -r 's/\<(William|John|...
Dies ist das ursprüngliche Skript
quelle
Das () erfasst den Nicht-Vornamen vor einem Nachnamen, sodass sie beim Ersetzen zurückverfolgt werden.
Bearbeiten
@ Manatwork, Gilles
Du hast recht. Wie wäre es mit
Dies scheint den Trick zu tun.
quelle
[^John]
einstimmt Charakter , die aus einer sein mussJ
,o
,h
odern
. Ich bezweifle, dass Sie das beabsichtigt haben. In regulären Ausdrücken gibt es kein Negationskonstrukt (Perl hat(?!…)
und(?<!…)
, aber wenn Sie es als Negation betrachten, wird es wahrscheinlich nicht das tun, was Sie erwarten).sed
ohne sie zu einer aufgeblähten Logik führt ...temp1
wird fast immer in Ordnung sein, aber! Pass auf den Bus auf. Um diese Möglichkeit abzuschwächen, ist es meines Erachtens besser, Zeichen zu verwenden, die (fast) nie in Textdateien mit lateinischer Schrift vorkommen, z. B. Hex-Wert \ x01 \ x02 oder Kombinationen davon oder möglicherweise das UTF-8-Gebietsschema \ xe188b4 (ሴ - ÄTHIOPISCH SYLLABLE SEE) .. zB.echo -e 'Z' |sed 's/./\xe1\x88\xb4/'
=>ሴ
wenn das Gebietsschema UTF-8 ist ..