如何删除每个模式匹配并将其写入新文件

如何删除每个模式匹配并将其写入新文件

所以我有一个没有空格的长字符串,我想在每次模式匹配时删除。该字符串如下所示:

bdy11<entryunit="phoenix"><name>costperdps</name><value>27.75</value></entry><entryunit="phoenix"><name>damage</name><value>5</value></entry><entrbdy623yunit="phoenix"><name>dps</name><value>9.01</value></entry><entryunit="phoenix"><name>dpsplusbonus</name><value>18.02</value></entry><entryunit="phoenix"><name>dpsplusupgbonus</name><value>23.42</value></entry><entryunit="phoenix"><name>dpsplusupgrades</name><value>14.41</value></entry><entryunit="phoenix"><name>range</name><value></value></entry><entryunit="phoenix"><name>targets</name><value>air</value></entry><entryunit="phoenix"><name>upgrade</name><value>1</value></entry><entryunit=bdy624"phoenix"><name>upgrade_damage</name><value></value></entry><entryunit="photoncannon"><name>attack</name><value>1</value></entry><entryunit="photoncannon"><name>bonus_damage</name><value></value></entry><entryunit="photoncannon"><name>bonus_type</name><value></value></entry><entryunit="photoncannon"><name>cooldown</name><value>1.25</value></entry><entryunit="photoncannon"><name>costperdps</name><value>9.38</value></entry><entryunit="photoncannon"><name>damage</name><value>20</value><bdy625/entry><entryunit="photoncannon"><name>dps</name><value>16.00</value></entry><entryunit="photoncannon"><name>dpsplusbonus</name><value></value></entry><entryunit="photoncannon"><name>dpsplusupgbonus</name><value></value></entry><entryunit="photoncannon"><name>dpsplusupgrades</name><value>16.00</value></entry><entryunit="photoncannon"><name>range</name><value></value></entry><entryunit="photoncannon"><name>targets</name><value>both</value></entry><entryunit="photoncannon"><name>upgrbdy626ade</name><value></value></entry><entryunit="photoncannon"><name>upgrade_damage</name><value></value></entry><entryunit="probe"><name>attack</name><value>1</value></entry><entryunit="probe"><name>bonus_damage</name><value></value></entry><entryunit="probe"><name>bonus_type</name><value></value></entry><entryunit="probe"><name>cooldown</name><value>1.50</value></entry><entryunit="probe"><name>costperdps</name><value>15.00</value></entry><entryunit="probe"><name>damage</name><value>5</valubdy627e></entry><entryunit="probe"><name>dps</name><value>3.33</value></entry><entryunit="probe"><name>dpsplusbonus</name><value></value></entry><entryunit="probe"><name>dpsplusupgbonus</name><value></value></entry><entryunit="probe"><name>dpsplusupgrades</name><value>3.33</value></entry><entryunit="probe"><name>range</name><value></value></entry><entryunit="probe"><name>targets</name><value>ground</value></entry><entryunit="probe"><name>upgrade</name><value></value></entry><entryunit="probe">bdy628<name>upgrade_damage</name><value></value></entry><entryunit="sentry"><name>attack</name><value>1</value></entry><entryunit="sentry"><name>bonus_damage</name><value></value></entry><entryunit="sentry"><name>bonus_type</name><value></value></entry><entryunit="sentry"><name>cooldown</name><value>1.00</value></entry><entryunit="sentry"><name>costperdps</name><value>25.00</value></entry><entryunit="sentry"><name>damage</name><value>6</value></entry><entryunit="sentry"><name>dps</name><value>6bdy629.00</value></entry><entryunit="sentry"><name>dpsplusbonus</name><value></value></entry><entryunit="sentry"><name>dpsplusupgbonus</name><value></value></entry><entryunit="sentry"><name>dpsplusupgrades</name><value>9.00</value></entry><entryunit="sentry"><name>range</name><value></value></entry><entryunit="sentry"><name>targets</name><value>both</value></entry><entryunit="sentry"><name>upgrade</name><value>1</value></entry><entryunit="sentry"><name>upgrade_damage</name><value></value></entrbdy630y><entryunit="stalker"><name>attack</name><value>1</value></entry><entryunit="stalker"><name>bonus_damage</name><value>4</value></entry><entryunit="stalker"><name>bonus_type</name><value>armored</value></entry><entryunit="stalker"><name>cooldown</name><value>1.44</value></entry><entryunit="stalker"><name>costperdps</name><value>25.20</value></entry><entryunit="stalker"><name>damage</name><value>10</value></entry><entryunit="stalker"><name>dps</name><value>6.94</value></entry><entryunit="bdy631stalker"><name>dpsplusbonus</name><value>9.72</value></entry><entryunit="stalker"><name>dpsplusupgbonus</name><value>11.81</value></entry><entryunit="stalker"><name>dpsplusupgrades</name><value>9.03</value></entry><entryunit="stalker"><name>range</name><value></value></entry><entryunit="stalker"><name>targets</name><value>both</value></entry><entryunit="stalker"><name>upgrade</name><value>1</value></entry><entryunit="stalker"><name>upgrade_damage</name><value></value></entry><entryunit="vbdy632oidray"><name>attack</name><value>1</value></entry><entryunit="voidray"><name>bonus_damage</name><value>4</value></entry><entryunit="voidray"><name>bonus_type</name><value>armored</value></entry><entryunit="voidray"><name>cooldown</name><value>.60</value></entry><entryunit="voidray"><name>costperdps</name><value>35.00</value></entry><entryunit="voidray"><name>damage</name><value>6</value></entry><entryunit="voidray"><name>dps</name><value>10.00</value></entry><entryunit="voidray">bdy633<name>dpsplusbonus</name><value>16.67</value></entry><entryunit="voidray"><name>dpsplusupgbonus</name><value>21.67</value></entry><entryunit="voidray"><name>dpsplusupgrades</name><value>15.00</value></entry><entryunit="voidray"><name>range</name><value></value></entry><entryunit="voidray"><name>targets</name><value>both</value></entry><entryunit="voidray"><name>upgrade</name><value>1</value></entry><entryunit="voidray"><name>upgrade_damage</name><value></value></entry><entryunit="vobdy634idraycharged"><name>attack</name><value>1</value></entry><entryunit="voidraycharged"><name>bonus_damage</name><value>8</value></entry><entryunit="voidraycharged"><name>bonus_type</name><value>armored</value></entry><entryunit="voidraycharged"><name>cooldown</name><value>.60</value></entry><entryunit="voidraycharged"><name>costperdps</name><value>26.25</value></entry><entryunit="voidraycharged"><name>damage</name><value>8</value></entry><entryunit="voidraycharged"><name>dps</nbdy635ame><value>13.33</value></entry><entryunit="voidraycharged"><name>dpsplusbonus</name><value>26.67</value></entry><entryunit="voidraycharged"><name>dpsplusupgbonus</name><value>36.67</value></entry><entryunit="voidraycharged"><name>dpsplusupgrades</name><value>18.33</value></entry><entryunit="voidraycharged"><name>range</name><value></value></entry><entryunit="voidraycharged"><name>targets</name><value>both</value></entry><entryunit="voidraycharged"><name>upgrade</name><value>1<bdy636/value></entry><entryunit="voidraycharged"><name>upgrade_damage</name><value>1</value></entry><entryunit="zealot"><name>attack</name><value>2</value></entry><entryunit="zealot"><name>bonus_damage</name><value></value></entry><entryunit="zealot"><name>bonus_type</name><value></value></entry><entryunit="zealot"><name>cooldown</name><value>1.20</value></entry><entryunit="zealot"><name>costperdps</name><value>7.50</value></entry><entryunit="zealot"><name>damage</name><value>8</value></entrybdy637><entryunit="zealot"><name>dps</name><value>13.33</value></entry><entryunit="zealot"><name>dpsplusbonus</name><value></value></entry><entryunit="zealot"><name>dpsplusupgbonus</name><value></value></entry><entryunit="zealot"><name>dpsplusupgrades</name><value>18.33</value></entry><entryunit="zealot"><name>range</name><value></value></entry><entryunit="zealot"><name>targets</name><value>ground</value></entry><entryunit="zealot"><name>upgrade</name><value>1</value></entry><entryunit="zealotbdy638"><name>upgrade_damage</name><value></value></entry></record>trl000000204000001410

我想每次删除 bdy 后跟 2 位数字和 bdy 后跟 3 位数字。到目前为止,我尝试将 sed 与正则表达式一起使用,但我相信正则表达式中有一个错误

sed 's/(.*bdy\d\d)//g; s/(.*bdy\d\d\d)//g' newTarget

我计划使用管道来转换文本

sed -e "
  s|<tag>|\n&|
  s/.*\n//
  s|</tag>|&\n|
  /\n/P;D
" newTarget > newTarget2

为了将每个标签放在新行上,以便更容易提取标签之间的数据,但在执行此操作之前,我需要删除 bdy 后跟数字,因为出现在标签之间。

答案1

我假设您想将字符串转换为有效的 XML。您不仅需要删除bdy字符串,还需要修复entry标签及其unit属性(目前一起写为),在开头entryunit添加缺少的开始标签并删除最后的字符串。<record>trl

您可以使用echo和执行此操作sed,然后使用以下命令重新格式化以提高可读性xmlstarlet

{
    echo '<record>'
    sed -e 's/bdy[0-9]\{2,3\}//g' \
        -e 's/entryunit/entry unit/g' \
        -e 's/trl[0-9]*$//' file
} | xmlstarlet fo

或者,在一行中,

{ echo '<record>'; sed -e 's/bdy[0-9]\{2,3\}//g' -e 's/entryunit/entry unit/g' -e 's/trl[0-9]*$//' file; } | xmlstarlet fo

xmlstarlet仅当您想很好地重新格式化文档时才需要该位。如果不重新格式化,XML 解析器仍然能够毫无问题地读取它。

sed命令首先删除所有bdy字符串。我们bdy使用 来匹配子字符串后面的一位或两位数字[0-9]\{2,3\},这意味着“0 到 9 之间的两位或三位数字”。

entryunit字符串被更正为entry unit使用简单的替换。

我们删除trl最后一次替换的字符串和尾随数字字符串。

通过xmlstarlet重新格式化,您的输出应该如下所示:

<?xml version="1.0"?>
<record>
  <entry unit="phoenix">
    <name>costperdps</name>
    <value>27.75</value>
  </entry>
  <entry unit="phoenix">
    <name>damage</name>
    <value>5</value>
  </entry>

[...]

  <entry unit="zealot">
    <name>upgrade</name>
    <value>1</value>
  </entry>
  <entry unit="zealot">
    <name>upgrade_damage</name>
    <value/>
  </entry>
</record>

无论您xmlstarlet稍后是否重新格式化生成的 XML 文档,您都可以使用该工具提取数据,如下所示:

xmlstarlet sel -t -v '//entry[@unit="photoncannon" and name="cooldown"]/value' -nl file

上面输出的是属性为、子节点值为 的value节点的值。换句话说,它获取光子炮的冷却值。entryunitphotoncannonnamecooldown

使用从 shell 变量获取的参数:

unit=photoncannon
name=cooldown
xmlstrlet sel -t \
    --var unit="'$unit'" \
    --var name="'$name'" \
    -v '//entry[@unit=$unit and name=$name]/value' -nl file

(请注意所使用的特定引号;内部变量$unit$name必须包含 XML 编码的字符串,这意味着它们需要添加显式引号。)

显然,您可以使用任何其他 XML 解析器来完成相同的操作。以下用途xq(来自这里),它是一个位于 JSON 解析器之上的 XML 解析器jq,这意味着它首先将 XML 文档转换为 JSON,然后调用jq解析结果数据:

unit=photoncannon
name=cooldown
xq -r \
    --arg unit "$unit" \
    --arg name "$name" \
    '.record.entry[] | select(."@unit" == $unit and .name == $name).value' file

相关内容