2012-11-13 15 views
15

クイック概要:ノード内のテキストを毎週自動的に変更するには、Bashスクリプトを作成する必要があります。スクリプトはノードにマッチし、その中のテキストを置き換えます(可能な場合)。どうすればいい?XMLファイルの動的コンテンツを置き換えてください

ロング概要: 私は/ ShowcaseStandalone/FFS-ストレージ/ディレクトリ内に自分の.xmlファイルを持っているそれぞれのお店を、持っているのMinecraftサーバーをホストします。毎週日曜日にサーバーが再起動し、いくつかのコマンドをターミナルに実行していくつかのものをリセットします。私が変えようとしていることは、お店の一つです。ノード<のitemstack >のテキストとノード<のテキスト>のテキストを変更したいと思います。私は単純に別のフォルダの.txtファイルからテキストを取り出し、それをそのノードに挿入したいと思っています。問題は、ノード内のテキストが毎週変わるということです。 bashを使って2つのノード内の特定の行やテキストを置き換える方法はありますか?

XMLファイル:

<?xml version="1.0" encoding="UTF-8"?> 
<scs-shop usid="cac8480951254352116d5255e795006252d404d9" version="2" type="storage"> 
    <enchantments type="string"/> 
    <owner type="string">Chadward27</owner> 
    <world type="string">Frisnuk</world> 
    <itemStack type="string">329:0</itemStack> 
    <activity type="string">BUY</activity> 
    <price type="double">55.0</price> 
    <locX type="double">487.5</locX> 
    <locY type="double">179.0</locY> 
    <locZ type="double">-1084.5</locZ> 
    <amount type="integer">0</amount> 
    <maxAmount type="integer">0</maxAmount> 
    <isUnlimited type="boolean">true</isUnlimited> 
    <nbt-storage usid="23dffac5fb2ea7cfdcf0740159e881026fde4fa4" version="2" type="storage"/> 
</scs-shop> 

オペレーティングシステム:のLinuxのUbuntu 12.04

+0

だから、あなただけのSCS-ショップトンからUSID変更したいですアグ? –

+2

排他的に 'bash'を使ったXML操作ですか?なぜあなた自身を制限するのですか? –

+0

@sputnick申し訳ありませんが、私のノードを殺してしまったので&gtタグと&gtタグを付けなければなりませんでしたが、ノード "textstack"と "price"のテキストを置き換える必要があります – Clucky

答えて

16

あなたはこのようなshellXMLファイルを編集するxmlstarletを使用することができます。

xmlstarlet edit -L -u "/scs-shop/price[@type='double']" -v '99.66' file.xml 

NOTE

  • ​​はXpath表現
  • は、XMLの道は涼しいですが、通常のbashのツールを使用する必要がある場合、あなたはSEDを使用して行を変更することができxmlstarlet ed --help
+0

私はあなたが私のためにすべての仕事をすることを意味するわけではありませんが、私は視覚的な学習者です。 " 55.0 "を " 25.0 "に置き換えるにはどうすればよいですか? – Clucky

+0

あなたに私に有効なXMLを与えるなら、あなたに完全な構文を与えることができます –

+0

これは次のようにテストできます: 'xmlstarlet val file.xml' –

10

を参照してくださいされています。例えば:

PRICE=123 
sed -i "s/\(<price.*>\)[^<>]*\(<\/price.*\)/\1$PRICE\2/" $XML_FILE_TO_MODIFY 

これは、コマンドが困難なようだsedの123

との価格に置き換えられますので、私はそれを打破してみましょう:

\(<price.*>\)[^<>]*\(<\/price.*\)がマッチするパターンです。 \( ... \)はグループ化の括弧です。 <price.*>は開始価格タグと一致します。 [^<>]*は山カッコ以外のものと一致し、この場合は価格タグの内容と一致します。 <\/price.*は、価格タグの末尾と一致します。前方スラッシュはsedの区切り文字なので、バックスラッシュでエスケープします。

\1$PRICE\2は、一致するテキストを置き換えるテキストです。 \1は、開始価格タグである最初の一致したかっこグループを参照します。 $PRICEは、希望する価格の変数です。 \2は、2番目のカッコグループを指します。この場合は、終了タグです。

+4

これは間違った方法です。 Bash、grep、sed、cutなどを使って、HTMLやXMLなどのタグベースのマークアップ言語を現実的に解析することはできません。http://www.codinghorror.com/blog/archives/001311.htmlを参照してください(ブログのウェブサイトこれはHTMLに関するものですが、これはXMLでも同じです... –

+2

linuxにxmlstarletのような良いxmlツールがあれば、これは間違った方法であると私は同意します。それが起こるまで、sedは私のゴーイングツールです。現実的には、これを含む99%のケースでsedを使用することができます。 –

+1

私は "それはうまくいかない"とは言っていませんが、 "それは信頼できません"。このような単純なケースでは、これは一部の人にとっては「うまくいく」ようですが、ネストされたタグでXMLがより複雑になるとどうなりますか?私はものを清潔にするための信頼できる方法について話しています。 'sudo apt-get install xmlstarlet'は大したことではありません。 –

1

私はxmlstarletを持っているという贅沢はありませんでした。 インライン置換を行うだけで解決策が見つかりました。

テンプレート-parameter.xml

<ns:Parameter> 
    <ns:Name required="true">##-ParamName-##</ns:Name> 
    <ns:Value> 
     <ns:Text>##-ParamValue-##</ns:Text> 
    </ns:Value> 
</ns:Parameter> 

スニペット

tokenName="foo" 
tokenValue="bar"  

#Replace placeholders in parameter template element 
myParamElement=$(cat template-parameter.xml) 
myParamElement=${myParamElement//##-ParamName-##/$tokenName} 
myParamElement=${myParamElement//##-ParamValue-##/$tokenValue} 

結果

<ns:Parameter> 
    <ns:Name required="true">foo</ns:Name> 
    <ns:Value> 
     <ns:Text>bar</ns:Text> 
    </ns:Value> 
</ns:Parameter> 
関連する問題