我需要一个 bash 脚本,将文件中两个箭头之间的每个数字替换为 0

我需要一个 bash 脚本,将文件中两个箭头之间的每个数字替换为 0

该文件的名称是 types.xml,列出了数百个不同的项目。

这是它的样子:

    <type name="CanisterGasoline">
        <nominal>50</nominal>
        <lifetime>28800</lifetime>
        <restock>0</restock>
        <min>30</min>
        <quantmin>-1</quantmin>
        <quantmax>-1</quantmax>
        <cost>100</cost>
        <flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/>
        <category name="tools"/>
        <tag name="shelves"/>
        <usage name="Industrial"/>
    </type>
    <type name="Canteen">
        <nominal>20</nominal>
        <lifetime>14400</lifetime>
        <restock>0</restock>
        <min>10</min>
        <quantmin>10</quantmin>
        <quantmax>90</quantmax>
        <cost>100</cost>
        <flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/>
        <category name="food"/>
        <usage name="Military"/>
    </type>

基本上,无论它说什么,我都想将和<nominal>20</nominal>之间的数字更改为 0。<nominal></nominal>

感谢您抽出宝贵的时间!

答案1

如果你想这样做,sed你可以这样做:

sed 's@<nominal>[0-9]*</nominal>@<nominal>0</nominal>@' types.xml > output.xml

它将替换<nominal>后跟任何数字序列,后跟</nominal>with <nominal>0</nominal>

但我相信很快就会有人提出建议为什么应该使用专用的 XML 解析器来完成此任务,并建议使用哪个解析器以及如何使用。

答案2

假设 XML 文档格式良好(您的示例缺少根节点),如果节点的值为 20,您可以xmlstarlet将任何 -node 的值替换为 0,如下所示:nominal

xmlstarlet ed -u '//nominal[text() = 20]' -v 0  types.xml

这通过更新 ()输入文档 ( ) 中值为 20 () 的所有节点,并将节点的值设置为零 ( ) 来编辑 ( ed) 数据。-unominal//nominal[text() = 20]-v 0

将根节点添加到示例文档并运行此结果

<?xml version="1.0"?>
<root>
  <type name="CanisterGasoline">
    <nominal>50</nominal>
    <lifetime>28800</lifetime>
    <restock>0</restock>
    <min>30</min>
    <quantmin>-1</quantmin>
    <quantmax>-1</quantmax>
    <cost>100</cost>
    <flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/>
    <category name="tools"/>
    <tag name="shelves"/>
    <usage name="Industrial"/>
  </type>
  <type name="Canteen">
    <nominal>0</nominal>
    <lifetime>14400</lifetime>
    <restock>0</restock>
    <min>10</min>
    <quantmin>10</quantmin>
    <quantmax>90</quantmax>
    <cost>100</cost>
    <flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/>
    <category name="food"/>
    <usage name="Military"/>
  </type>
</root>

xmlstarlet甚至可以使用文档中的其他值更新该值,例如父节点的restock值:

xmlstarlet ed -u '//nominal[text() = 20]' -x '../restock/text()'  types.xml

如果您在命令行后立即给出或选项,则该xmlstarlet实用程序可以进行就地编辑。-L--inplaceed

答案3

或者使用 的regex“反向引用”,例如

sed 's@\(<nominal>\)[0-9]*\(</nominal>\)@\10\2@' types.xml

相关内容