web-dev-qa-db-ja.com

sedを使用して文字列をXMLファイルの特殊文字に置き換える

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

私がここで何を見逃しているのか分かりますか?

6
rolinrok

シェル変数を一重引用符で囲むと、その解釈が無効になります。そのため、コマンドは効果がありません。

$ 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
2
Rajish

これはあなたに役立つかもしれません:
コマンドラインXML操作
http://xmlstar.sourceforge.net/

AFAICR
apt-get install xmlstarlet

0
user19496