Grepを使用して同じ文字列を見つけるのに問題がないにもかかわらず、XMLファイル内のテキストの文字列をsedで置き換えるのに問題があります。置き換えられる新しい文字列と古い文字列には多くの特殊文字が含まれているため、多数の円記号を使用するのではなく、変数に格納するのが最善だと思いました。
OLD_STRING='<property name="webServiceHost">${jboss.bind.address}</property>'
NEW_STRING='<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'
文字列は期待どおりに保存されているようです。
$ echo $OLD_STRING; echo $NEW_STRING
<property name="webServiceHost">${jboss.bind.address}</property>
<!--<property name="webServiceHost">${jboss.bind.address}</property>-->
Grepを実行すると、古い文字列がXMLファイルに存在することが確認されます。
$ grep "$OLD_STRING" jboss-beans.xml
<property name="webServiceHost">${jboss.bind.address}</property>
ただし、次のsedコマンドは出力をまったく生成しません。
sed -i 's/"$OLD_STRING"/"$NEW_STRING"/g' jboss-beans.xml
私がここで何を見逃しているのか分かりますか?
シェル変数を一重引用符で囲むと、その解釈が無効になります。そのため、コマンドは効果がありません。
$ echo 's/"$OLD_STRING"/"$NEW_STRING"/g'
s/"$OLD_STRING"/"$NEW_STRING"/g
次のように書く必要があります。
sed -i "s/'$OLD_STRING'/'$NEW_STRING'/g" jboss-beans.xml
しかし、変数は解釈されますbeforesed
を呼び出し、再び特殊文字が含まれます:
$ echo "s/'$OLD_STRING'/'$NEW_STRING'/g"
s/'<property name="webServiceHost">${jboss.bind.address}</property>'/'<!--<property name="webServiceHost">${jboss.bind.address}</property>-->'/g
そのため、sed
にはこの特別な機能があり、s///
コマンド区切り文字を使用するだけで定義できます。例:
sed -i "s#'$OLD_STRING'#'$NEW_STRING'#g" jboss-beans.xml
それでも、検索式には特別な正規表現文字が含まれており、このようにsed
を使用することはその能力の無駄です。私は次のような式を書きます:
sed -i 's/\(<.*webServiceHost.*jboss.bind.address.*>\)/<!--\1-->/' jboss-beans.xml
もちろん、必要に応じて一致文字列を多かれ少なかれ具体的にすることができます。役立つ他の素晴らしい機能もあります。 sed
を使用すると、編集操作を特定のパターンに一致する行に絞り込むことができます。コマンドは次のようになります。
sed -i '/webServiceHost/ s/^\(.*\)$/<!--\1-->/' jboss-beans.xml
これはあなたに役立つかもしれません:
コマンドラインXML操作
http://xmlstar.sourceforge.net/
AFAICR
apt-get install xmlstarlet