
ファイル内で と を と に置き換えていました。これは、hmtl タグを置き換えるようなものです。 を使用しました<B>
。</B>
これ<STRONG>
で問題は解決しましたが、ファイル内にとが存在する場合、これらもとに変更されます。その背後にあるロジックがわかりません。</STRONG>
sed 's/\<B\>/STRONG/g'
[B]
[/B]
[STRONG]
[/STRONG]
答え1
デフォルトでは、sed は基本的な正規表現を使用します。つまり、GNU lets は\<
単語の先頭に一致し、\>
単語の末尾に一致します。次の点に注意してください。
$ echo '<B> BBB B' | sed 's/\<B\>/STRONG/g'
<STRONG> BBB STRONG
\<B\>
B
上記の文字列に 2 回出現する単語と一致します。単語と一致しB
、山括弧とは一致しないため、山括弧は変更されません。
山括弧を一致させたい場合、<>
バックスラッシュを省略します。
$ echo '<B> BBB B' | sed 's/<B>/<STRONG>/g'
<STRONG> BBB B
<B>
開き山括弧、その後にB
閉じ山括弧が続くものと一致します。したがって、<B>
は に置き換えられます<STRONG>
が、B
そのまま残ります。
開始タグと終了タグの両方をキャッチする
$ echo '<B> BBB B </B>' | sed -r 's|<(/)?B>|<\1STRONG>|g'
<STRONG> BBB B </STRONG>
-r
は拡張正規表現用ですが、GNU sed の最近のバージョンで-E
は の同義語としてもサポートされています-r
。BSD sed は-E
これに対して を使用し、報告によると、将来の POSIX 標準では が採用される予定です-E
。したがって、互換性のために、 を使用することをお勧めします (ヒント @Kos):
$ echo '<B> BBB B </B>' | sed -E 's|<(/)?B>|<\1STRONG>|g'
<STRONG> BBB B </STRONG>
答え2
<
特殊文字では>
ない基本的な正規表現なので、エスケープしてはいけません。エスケープすると、sed
特殊文字として扱おうとし、その後の動作は次のようになります。未定義:
( '\' ) が前に付いた通常の文字の解釈は、次の場合を除いて未定義です。
- 文字 ')'、'('、'{'、および '}'
- 1から9までの数字(複数の文字に一致する BRE)
- 括弧内の文字
したがって、エスケープせずに<
and を使用します>
。
$ echo 'b<b>' | sed 's/<b>/strong/'
bstrong
答え3
の解決策awk
。ここには2行のサンプルファイルがあります。そしてタグを抽出し、gsub
関数を使用して置き換えます。次に、それを一時ファイルに出力し、元のファイルに戻します。完了したら一時ファイルを削除します。必要に応じて調整します。
$ 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