PERCENT=""
上記のフィールド内の数値を半分にしたいと思います10000
。この数字には小数点以下の桁数を含めることはできません。たとえばPERCENT="50001" would need to be PERCENT="25001" or PERCENT="25000"
(私の例では25001が使用されていますが、重要ではありません)。すべてのデータも1行にあるため、その状態を維持する必要があります。以下の例
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="13" ITEM_ID="0" AMOUNT="6500" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="11250" ITEM_ID="31" AMOUNT="1" GROUPING="3" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="7000" ITEM_ID="165" AMOUNT="1" GROUPING="2" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="47500" ITEM_ID="167" AMOUNT="1" GROUPING="2" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="10" ITEM_ID="179" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="20" ITEM_ID="179" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="60" ITEM_ID="180" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="12223" ITEM_ID="180" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="50001" ITEM_ID="206" AMOUNT="1" GROUPING="2" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="2000" ITEM_ID="273" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" />
結果は次のとおりです。
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="13" ITEM_ID="0" AMOUNT="6500" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="5625" ITEM_ID="31" AMOUNT="1" GROUPING="3" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="7000" ITEM_ID="165" AMOUNT="1" GROUPING="2" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="23750" ITEM_ID="167" AMOUNT="1" GROUPING="2" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="10" ITEM_ID="179" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="20" ITEM_ID="179" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="60" ITEM_ID="180" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="6112" ITEM_ID="180" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="25001" ITEM_ID="206" AMOUNT="1" GROUPING="2" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="2000" ITEM_ID="273" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" />
答え1
XML に正しいルートタグがあると仮定する場合は、次のようにします。XMLスター:
$ xml ed -u '//VALUE/@PERCENT[. > 10000]' -x 'floor(. * .5)' data.xml
このビットはXMLのすべてのノードを//VALUE
選択します。VALUE
彼らは/@PERCENT
自分の属性を選択しますPERCENT
。値が10,000を超える属性[. > 10000]
に選択を制限しますPERCENT
。編集するfloor(. * .5)
選択した値(0.5を掛けて半減)に関数を適用します。ここでは.
、以前と同様に値のプレースホルダです。
これはあなたに与えるでしょう
<?xml version="1.0"?>
<root>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="13" ITEM_ID="0" AMOUNT="6500" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="5625" ITEM_ID="31" AMOUNT="1" GROUPING="3" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="7000" ITEM_ID="165" AMOUNT="1" GROUPING="2" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="23750" ITEM_ID="167" AMOUNT="1" GROUPING="2" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="10" ITEM_ID="179" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="20" ITEM_ID="179" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="60" ITEM_ID="180" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="6111" ITEM_ID="180" AMOUNT="1" GROUPING="0" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="25000" ITEM_ID="206" AMOUNT="1" GROUPING="2" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
<VALUE MON_ID="10100" START_LV="1" END_LV="99" PERCENT="2000" ITEM_ID="273" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200"/>
</root>
答え2
実装に制限がなければ、Perlでは簡単です。
perl -p -e 's/PERCENT="(\d{5,})"/sprintf "PERCENT=\"%d\"",int($1\/2)/eg'
e
パターンに追加されたものは、s/../../
Perlに単純な置換を実行するのではなく、コマンドセットで2番目の部分を「実行」するように指示します。
これはg
、「最初の文字列だけでなく、見つかったすべての文字列に対してこれを実行する」という意味です。したがって、元のデータには次のものがあります。
PERCENT="13"
PERCENT="11250"
PERCENT="7000"
PERCENT="47500"
PERCENT="10"
PERCENT="20"
PERCENT="60"
PERCENT="12223"
PERCENT="50001"
PERCENT="2000"
結果は次のとおりです。
PERCENT="13"
PERCENT="5625"
PERCENT="7000"
PERCENT="23750"
PERCENT="10"
PERCENT="20"
PERCENT="60"
PERCENT="6111"
PERCENT="25000"
PERCENT="2000"
(数字のうち2つは丸めのため結果と異なります。あなたの質問によると、この場合は気にする必要はありません。)
これは少しトリックです。 10000より大きい数字は5桁以上である必要があるため、その数字を検索して見つけた値を元の値の半分に置き換えます。
ランダムな数字を切り捨てるには、より厳しいテストのために少し変更できます。
perl -p -e 's/PERCENT="(\d+)"/$x=$1; $x=int($x\/2) if $x>=10000; "PERCENT=\"$x\""/eg'
ここでは、テストを$x>=10000
必要に応じて変更できることがより明確になりました。
答え3
Bashでこれを試してください:
awk '
{
for (i=1;i<=NF;i++) {
split($i,perc,"\"")
if ($i ~ "PERCENT" && perc[2] >= 10000)
printf "%s\"%d\" ", perc[1], perc[2]/2
else
printf $i " "
}
}' $*