小さなbashスクリプト内でファイル内の文字列を置き換える必要がありますが...奇妙な結果が得られます。
交換したいとしましょう:
<tag><![CDATA[text]]></tag>
と:
<tag><![CDATA[replaced_text]]></tag>
使用する必要がありますsed
か? のせいだ/
と思い[
]
ますが、奇妙な結果が得られています...
これにアプローチする最良の方法は何ですか?
-p オプションを指定した Perl は sed とほぼ同じように動作し、正規表現用に \Q (引用符) スイッチがあります。
perl -pe 's{\Q<tag><![CDATA[text]]></tag>}
{<tag><![CDATA[replaced_text]]></tag>}' YOUR_FILE
Perl では、さまざまな句読点を使用して式を区切ることができます (私の例では s{...}{...})。
はい、括弧をエスケープする必要があり、スラッシュをエスケープするか、別の区切り文字を使用する必要があります。
sed 's,<tag><!\[CDATA\[text\]\]></tag>,<tag><!\[CDATA\[replaced)text\]\]></tag>,'
とはいえ、正規表現の使用に関しては、実際には SGML と XML がHTMLより優れているわけではありません。これが一般化するとは思わないでください。
/ 以外の区切り文字を使用してください。ここでは # を使用します。
sed -i 's#<tag><!\[CDATA\[text\]\]></tag>#<tag><![CDATA[replaced_text]]></tag>#g' filename
-i
ファイルを印刷する代わりに、sed でファイルを変更します。
g
複数回一致するためのものです(グローバル)。
しかし、一致させたい正確な文字列 (タグとテキストの両方) を知っていますか? たとえば、テキストをすべて Replaceed_text に置き換えたい場合は、次のようにします。
perl -i -pe 's#(<tag><!\[CDATA\[)(.*?)(\]\]></tag>)#\1replaced_text\3#g' filename
sed は貪欲でない乗数 (*?) をサポートしていないため、perl に切り替えました。
これで十分です:
$ echo '<tag><![CDATA[text]]></tag>' | sed 's/\[text\]/\[replaced_text\]/'
<tag><![CDATA[replaced_text]]></tag>
/
sed 内のセパレーターを,
,|
やなどの別の文字に
変更することもできます%
。