特定のフィールドの数値を除外

特定のフィールドの数値を除外

PERCENT=""データフィールド内の数字をSTART_LV=""合計で除算したいと思いますEND_LV=""。しかし、数字を5で割りたいです。数字は整数でなければなりません。また、現在の数字が5未満の場合は、次のように設定する必要があります。PERCENT="1"

サンプルデータは次のとおりです。

<VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="333" ITEM_ID="992" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="626" ITEM_ID="993" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="555" ITEM_ID="994" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="1" ITEM_ID="995" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="4" ITEM_ID="996" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="5" ITEM_ID="997" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="300" ITEM_ID="998" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="350" ITEM_ID="1025" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" />

次のように変更する必要があります。

<VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="66" ITEM_ID="992" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="125" ITEM_ID="993" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="111" ITEM_ID="994" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="1" ITEM_ID="995" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="1" ITEM_ID="996" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="1" ITEM_ID="997" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="60" ITEM_ID="998" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" /><VALUE MON_ID="30016" START_LV="1" END_LV="99" PERCENT="70" ITEM_ID="1025" AMOUNT="1" GROUPING="1" DROPSET="0" ZONELEVEL="GSP" VER="200" />

データは行で区切られません。また、小数点以下の桁数を持つ数字は丸めたり下げたりすることができ、整数であれば問題になりません。

答え1

ファイルが正しい形式のXMLファイルであると仮定すると、それを使用してxmlstarlet属性値を更新できます。

xmlstrlet ed -u '//VALUE/@PERCENT' -x 'ceiling(. div 5)' file.xml

その後、XMLを読み取り、file.xmlノードVALUEPERCENT属性値を5で割って結果を丸めます。生成されたXML文書は標準出力として作成されるため、単に新しい文書にリダイレクトできます。

丸めた後にゼロになる数値を変更することもできます。

xmlstarlet ed -u '//VALUE/@PERCENT'        -x 'floor(. div 5)' \
              -u '//VALUE/@PERCENT[. = 0]' -v 1 file.xml

または、5以上の数字のみを分割し、より小さい数字を1に設定します。

xmlstarlet ed -u '//VALUE/@PERCENT[. <  5]' -v 1 \
              -u '//VALUE/@PERCENT[. >= 5]' -x 'floor(. div 5)' file.xml

ここで作業順序に注意してください。値を5で割ると値が小さくなるため、値を1に設定したくありません。

答え2

tr -s " " "\n" < data | while read -r a;do if [ ${a:0:7} = "PERCENT" ];then echo -n PERCENT=\"$((${a//[A-Z=\"]} / 5 ))\"\  ; else echo -n $a" ";fi;done

関連情報