
Ich habe in einer Datei <B>
und </B>
durch <STRONG>
und ersetzt </STRONG>
. Das ist ungefähr so, als würde man HTML-Tags ersetzen. Ich habe verwendet sed 's/\<B\>/STRONG/g'
. Das hat funktioniert, aber wenn in der Datei [B]
und vorhanden ist, werden sie auch in und [/B]
geändert . Ich verstehe die Logik dahinter nicht.[STRONG]
[/STRONG]
Antwort1
Standardmäßig verwendet sed einfache reguläre Ausdrücke. Das bedeutet, dass GNU \<
sowohl den Anfang eines Wortes als auch \>
das Ende eines Wortes abgleichen lässt. Beachten Sie:
$ echo '<B> BBB B' | sed 's/\<B\>/STRONG/g'
<STRONG> BBB STRONG
\<B\>
stimmt mit dem Wort überein B
, das in der obigen Zeichenfolge zweimal vorkommt. Da es mit dem Wort übereinstimmt B
und nicht mit den spitzen Klammern, bleiben die spitzen Klammern unverändert.
Wenn Sie spitze Klammern verwenden möchten, <>
lassen Sie den Backslash weg:
$ echo '<B> BBB B' | sed 's/<B>/<STRONG>/g'
<STRONG> BBB B
<B>
entspricht einer öffnenden spitzen Klammer, gefolgt B
von einer schließenden spitzen Klammer. <B>
Wird also durch ersetzt , <STRONG>
aber B
unverändert gelassen.
Erfassen sowohl der öffnenden als auch der schließenden Tags
$ echo '<B> BBB B </B>' | sed -r 's|<(/)?B>|<\1STRONG>|g'
<STRONG> BBB B </STRONG>
-r
ist für erweiterte reguläre Ausdrücke, aber neuere Versionen von GNU sed unterstützen auch -E
als Synonym für -r
. BSD sed verwendet -E
hierfür und Berichten zufolge haben zukünftige POSIX-Standards übernommen -E
. Aus Kompatibilitätsgründen kann man daher Folgendes verwenden (Hut ab, @Kos):
$ echo '<B> BBB B </B>' | sed -E 's|<(/)?B>|<\1STRONG>|g'
<STRONG> BBB B </STRONG>
Antwort2
<
und >
sind keine Sonderzeichen inGrundlegende reguläre Ausdrücke, daher sollten sie nicht maskiert werden. Wenn Sie sie maskiert haben, sed
wird versucht, sie als Sonderzeichen zu behandeln, und dann ist das Verhaltennicht definiert:
Die Interpretation eines gewöhnlichen Zeichens, dem ein ( '\' ) vorangestellt ist, ist undefiniert, außer in folgenden Fällen:
- Die Zeichen ')', '(', '{' und '}'
- Die Ziffern 1 bis einschließlich 9 (sieheBREs, die mehreren Zeichen entsprechen)
- Ein Zeichen innerhalb eines Klammerausdrucks
Verwenden Sie also einfach <
und >
ohne Escapezeichen:
$ echo 'b<b>' | sed 's/<b>/strong/'
bstrong
Antwort3
Lösung mit awk
. Hier habe ich eine Beispieldatei mit zwei Zeilen, die enthaltenUndTags und verwenden Sie gsub
die Funktion, um sie zu ersetzen. Dann geben wir das in eine temporäre Datei und zurück in die Originaldatei aus. Entfernen Sie die temporäre Datei, wenn Sie fertig sind. Passen Sie sie nach Bedarf an.
$ cat tags.txt
<B> and </B>
<B> or </B>
$ awk '{gsub("<B>","<STRONG>"); gsub("</B>","</STRONG>");print}' tags.txt
<STRONG> and </STRONG>
<STRONG> or </STRONG>
$ awk '{gsub("<B>","<STRONG>"); gsub("</B>","</STRONG>");print}' tags.txt > tmpfile.txt && cat tmpfile > tags.txt