2つのパターンの間にテキストを挿入する

2つのパターンの間にテキストを挿入する

.xml次の内容を含むファイルがあります。

<controller-host></controller-host>
 <controller-port></controller-port>
<tier-name></tier-name>
<node-name></node-name>

私はこの出力が欲しい

<controller-host>AppDynamicsHost</controller-host>
 <controller-port>80</controller-port>
<tier-name>**the host name**</tier-name>
<node-name>tomcat server</node-name>

使用しようとしましたが、sed動作しません。

答え1

そのファイルは有効なxmlではありません。開くと閉じるルートタグを追加する必要があります。このように:

<xml>
  <controller-host></controller-host>
  <controller-port></controller-port>
  <tier-name></tier-name>
  <node-name></node-name>
</xml>

この入力を使用すると、xmlパーサーを使用してxmlstartletコンテンツを編集できます。

xmlstarlet ed -O -u //controller-host -v "AppDynamicsHost" \
                 -u //controller-port -v "80" \
                 -u //tier-name -v "the hostname" \
                 -u //node-name -v "tomcat server" file
  • ed編集モードを開始xmlstartlet
  • -O<?xml version="1.0"?>宣言を省略
  • -u与えられたxpathを更新します。
  • -v与えられた値を設定

その後、出力は次のようになります。

<xml>
  <controller-host>AppDynamicsHost</controller-host>
  <controller-port>80</controller-port>
  <tier-name>the hostname</tier-name>
  <node-name>tomcat server</node-name>
</xml>

ファイルをその場で直接編集するには、このフラグを使用できます-L

答え2

次のように試すことができます。

$host='hostname'

sed -i 's/<controller-host><\/controller-host>/<controller-host>AppDynamicsHost<\/controller-host>/' yourfile.xml
sed -i 's/<controller-port><\/controller-port>/<controller-port>80<\/controller-port>' yourfile.xml
sed -i "s/<tier-name><\/tier-name>/<tier-name>${host}<\/tier-name>/' yourfile.xml
sed -i 's/<node-name><\/node-name>/<node-name>tomcat server<\/node-name>/' yourfile.xml

この-iフラグは、結果をファイルに記録し、-i同時テストなしで実行することを意味します。

答え3

Chaosが言ったように、ファイルを有効なXMLファイルにし、xmlstarlet同様のXML処理ツール(たとえばxsh)を使用するのが「正しい」答えです...しかし、単純なテンプレートを作成したい場合は、入力を変更します。変更したい場所でトークンを簡単に見つけて交換できるファイルです。たとえば、

<controller-host>__CONTROLLER__</controller-host>
 <controller-port>__PORT__</controller-port>
<tier-name>__HOSTNAME__</tier-name>
<node-name>__NODENAME__</node-name>

その後、一般的なツール(awk、sed、perl、rubyなど)を使用して、__CONTROLLER__etcを希望の実際の値に置き換えることができます。

注:テキストに表示されない文字列を使用することが重要です。だから、__例えば__PORT__、単にPORT

これは非常に単純なテンプレート要件に適しています。より複雑なテンプレートを実行する必要がある場合、多くの言語には非常に洗練されたテンプレートライブラリがあります。例えばperlText::Templateそして他の多くの言語は多くの解決策に触発された一般的な問題です)

関連情報