2012-11-13 8 views
15

में गतिशील सामग्री को बदलें त्वरित सारांश: मुझे प्रत्येक सप्ताह स्वचालित रूप से नोड के भीतर पाठ को बदलने के लिए एक बैश स्क्रिप्ट बनाने की आवश्यकता है। स्क्रिप्ट नोड से मेल खाएगी और उनके अंदर पाठ को प्रतिस्थापित करेगी (यदि यह संभव है)? यह मैं कैसे करूंगा?एक्सएमएल फ़ाइल

लांग सारांश: मैं एक Minecraft सर्वर जो दुकानें, जिनमें से प्रत्येक/ShowcaseStandalone/ffs भंडारण/निर्देशिका में अपने स्वयं के .xml फ़ाइल है है होस्ट करते हैं। प्रत्येक रविवार मेरा सर्वर कई चीजों को रीसेट करने के लिए टर्मिनल में कई आदेशों को पुनरारंभ करता है और निष्पादित करता है। एक चीज जिसे मैं बदलने की कोशिश कर रहा हूं वह दुकानों में से एक है। मैं नोड < आइटमस्टैक > में पाठ को बदलना चाहता हूं और नोड < मूल्य > में पाठ को बदलना चाहता हूं। मैं बस एक अलग फ़ोल्डर में .txt फ़ाइल से टेक्स्ट लेना चाहता हूं, और उसे उस नोड में डालें। समस्या यह है कि नोड में पाठ हर हफ्ते बदल जाएगा। क्या बैश का उपयोग करके दो नोड्स के भीतर एक विशिष्ट रेखा या पाठ को प्रतिस्थापित करने का कोई तरीका है?

एक्सएमएल फ़ाइल:

<?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> 

ऑपरेटिंग सिस्टम: लिनक्स Ubuntu 12.04

+0

तो आप बस से usid बदलना चाहते एससीएस दुकान टी एजी? –

+2

एक्सएमएल हेरफेर विशेष रूप से 'बैश' का उपयोग कर? खुद को सीमित क्यों करें? –

+0

@sputnick क्षमा करें, मुझे विज्ञापन और lt और gt टैग्स करना पड़ा क्योंकि यह मेरे नोड्स को मार डाला, लेकिन नहीं, मुझे नोड्स "itemstack" और "price" में टेक्स्ट को प्रतिस्थापित करने की आवश्यकता है – Clucky

उत्तर

16

आप एक shell इस तरह में xmlstarlet उपयोग कर सकते हैं एक XML फ़ाइल को संपादित करने के लिए:

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

नोट

  • "/scs-shop/price[@type='double']" एक Xpath अभिव्यक्ति
  • देख xmlstarlet ed --help
+0

मेरा मतलब यह नहीं है कि आप मेरे लिए सभी काम करें, लेकिन मैं एक दृश्य शिक्षार्थी हूं। < 55.0 "with" 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 

यह 123

साथ कीमत यही sed कमान चुनौतीपूर्ण लगता है की जगह लेगा, तो मुझे इसे तोड़ने को नीचा दिखाया:

\(<price.*>\)[^<>]*\(<\/price.*\) आकार से मिलान किया जा सके। \( ... \) समूहकरण के लिए ब्रांडेसिस हैं। <price.*> उद्घाटन मूल्य टैग से मेल खाता है। [^<>]* एंगल ब्रैकेट को छोड़कर कुछ भी मेल खाता है, और इस मामले में मूल्य टैग की सामग्री से मेल खाएगा। <\/price.* मूल्य टैग के अंत से मेल खाता है। फॉरवर्ड स्लैश sed में एक delimiter है, तो मैं इसे एक पीठ स्लैश के साथ भागने।

\1$PRICE\2 मिलान किए गए टेक्स्ट को प्रतिस्थापित करने के लिए पाठ है। \1 पहले मिलान किए गए कोष्ठक समूह को संदर्भित करता है, जो उद्घाटन मूल्य टैग है। $PRICE वैरिएबल है जिसमें वांछित कीमत है। \2 इस मामले में समापन टैग, दूसरे कोष्ठक समूह को संदर्भित करता है।

+4

यह गलत तरीका है। आप वास्तव में बाश, grep, sed, cut, आदि का उपयोग कर एचटीएमएल या एक्सएमएल जैसे टैग-आधारित मार्कअप भाषाओं को पार्स नहीं कर सकते हैं। Http://www.codinghorror.com/blog/archives/001311.html देखें (आप ब्लॉग वेबसाइट जानते हैं SO निर्माता से?) यह HTML के बारे में है, लेकिन यह XML के लिए समान है ... –

+2

यदि लिनक्स xmlstarlet जैसे अच्छे xml टूल के साथ आया तो मैं सहमत होगा कि यह गलत तरीका है। जब तक यह नहीं करता है, sed मेरा जाने-माने टूल है। वास्तव में, आप इस सहित 99% मामलों में sed का उपयोग कर सकते हैं। –

+1

मैंने नहीं कहा "यह काम नहीं करता" लेकिन: "यह विश्वसनीय नहीं है"। इस तरह के एक साधारण मामले में यह कुछ लोगों के लिए "ठीक" लगता है, लेकिन क्या होता है जब एक्सएमएल घोंसला वाले टैग के साथ अधिक जटिल हो जाता है? मैं चीजों को साफ करने के लिए विश्वसनीय तरीके के बारे में बात कर रहा हूं। 'sudo apt-get 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> 
संबंधित मुद्दे