所以我有一个没有空格的长字符串,我想在每次模式匹配时删除。该字符串如下所示:
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
节点的值。换句话说,它获取光子炮的冷却值。entry
unit
photoncannon
name
cooldown
使用从 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