Заменить динамический контент в XML файле
Краткая сводка: Мне нужно создать Bash script, чтобы автоматически менять текст в node каждую неделю. script будет соответствовать node и заменить текст внутри них (если это возможно)? Как мне это сделать?
Длинное резюме:
У меня есть сервер Minecraft, в котором есть магазины, каждый из которых имеет свой собственный .xml файл в каталоге /ShowcaseStandalone/ffs -storage/. Каждое воскресенье мой сервер перезапускает и выполняет несколько команд в терминале до reset несколько вещей. Одна вещь, которую я пытаюсь сделать, - это один из магазинов. Я хочу изменить текст в node <itemstack> и текст в node " цена > . Я просто хочу взять текст из .txt файла в другую папку и вставить его в node. Проблема в том, что текст в node будет меняться каждую неделю. Есть ли способ заменить определенную строку или текст в двух узлах с помощью bash?
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
Ответы
Ответ 1
Вы можете использовать xmlstarlet
для редактирования файла XML
в shell
следующим образом:
xmlstarlet edit -L -u "/scs-shop/price[@type='double']" -v '99.66' file.xml
Примечание
-
"/scs-shop/price[@type='double']"
- выражение Xpath
- см.
xmlstarlet ed --help
Ответ 2
XML-способ классный, но если вам нужно использовать обычные инструменты bash, вы можете изменить строку с помощью sed. Например:
PRICE=123
sed -i "s/\(<price.*>\)[^<>]*\(<\/price.*\)/\1$PRICE\2/" $XML_FILE_TO_MODIFY
Это заменит цену на 123.
Эта команда sed кажется сложной, поэтому позвольте мне сломать ее:
\(<price.*>\)[^<>]*\(<\/price.*\)
соответствует шаблону. \(
... \)
являются скобками для группировки. <price.*>
соответствует начальному ценнику. [^<>]*
соответствует чему угодно, кроме угловых скобок, и в этом случае будет соответствовать содержимому ценника. <\/price.*
соответствует концу ценника. Прямая косая черта - это разделитель в sed, поэтому я избегаю ее с обратной косой чертой.
\1$PRICE\2
- это текст для замены согласованного текста. \1
относится к первой сопоставленной группе скобок, которая является начальным ценовым тегом. $PRICE
- это переменная с желаемой ценой. \2
относится ко второй группе скобок, в этом случае закрывающий тег.
Ответ 3
У меня не было роскоши иметь 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>