10,000 を超える数値フィールドを半分に分割し、小数点を削除します。

10,000 を超える数値フィールドを半分に分割し、小数点を削除します。

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 " "
    }
}' $*

関連情報