単位のサフィックスが付いた数値の解析に便利ですか?


10

の出力など、人間が読める形式の数量のデータがありdu -h、それらの数値をさらに操作したいとします。そのデータのサブセットの合計を行うために、grepを介してデータをパイプしたいとします。これまでに見たことのない多くのシステムでこのアドホックを実行し、最小限のユーティリティしかありません。すべての標準10 ^ nサフィックスのサフィックス変換が必要です。

パイプライン内で接尾辞付きの数値を実数に変換するgnu-linuxユーティリティが存在しますか?これを行うために作成されたbash関数、または正規表現の置換やいくつかのsedステップの代わりに覚えやすいかもしれないperlがありますか?

38M     /var/crazyface/courses/200909-90147
2.7M    /var/crazyface/courses/200909-90157
1.1M    /var/crazyface/courses/200909-90159
385M    /var/crazyface/courses/200909-90161
1.3M    /var/crazyface/courses/200909-90169
376M    /var/crazyface/courses/200907-90171
8.0K    /var/crazyface/courses/200907-90173
668K    /var/crazyface/courses/200907-90175
564M    /var/crazyface/courses/200907-90178
4.0K    /var/crazyface/courses/200907-90179

| grep 200907 | <amazing suffix conversion> | awk '{s+=$1} END {print s}'


関連参照:


2
grepとawkを使用する必要はほとんどありません。awkを使用している場合は、awkを使用してください。ただ、追加/200907/例えば、あなたのあたりのラインコードの前にawk '/200907/{s+=$1} END {print s}'
トニー

回答:


14

あなたがリンクした質問の1つでの私の回答に基づいて:

awk '{
    ex = index("KMGTPEZY", substr($1, length($1)))
    val = substr($1, 0, length($1) - 1)

    prod = val * 10^(ex * 3)

    sum += prod
}
END {print sum}'

使用される別の方法:

sed 's/G/ * 1000 M/;s/M/ * 1000 K/;s/K/ * 1000/; s/$/ +\\/; $a0' | bc

2番目の方法の場合、サフィックスがsの場合はどうなりますか?
djuarez

@djuarez:sは何の乗数を表していますか?
追って通知があるまで一時停止。

なし。他のユニットケースを推定するだけです。
djuarez

@djuarez:それは意味がありません。この答えは、SIのサフィックスに関するものであり、一般的な単位ではありません(秒、おそらく?)sed私の回答でコマンドを拡張するには、コマンドに表示されているように、追加のSIサフィックスを処理する句を追加しますawks/T/ * 1000 G;たとえば、最初に追加するとテラバイトが追加されます。
追って通知があるまで一時停止。

3

これを行うには、perl正規表現を使用できます。例えば、

$value = 0;
if($line =~ /(\d+\.?\d*)(\D+)\s+/) {
   $amplifier = 1024 if ($2 eq 'K');
   $amplifier = 1024 * 1024 if ($2 eq 'M');
   $amplifier = 1024 * 1024 * 1024 if ($2 eq 'G');
   $value = $1 * $amplifier;
}

これは簡単なスクリプトです。それを出発点と考えることができます。お役に立てれば幸いです。


確かに、これは1つの方法です。また、stackoverflow.com / questions / 2557649 / …も見つかりました。

3

個人的には、私はそもそも-hフラグを使用しません。「人間が読める」バージョンでは、数値を四捨五入するため、変換時に再度四捨五入する必要があり、さらに精度が低下します。(たとえば、2.7MiBは2831155.2バイトです。他の0.8バイトのバイトで何をしましたか?!)

それ以外の場合は、unitsMiB / GiB / KiBを単に「B」に変換するように要求できます。これはこれを処理しますが、次のようにする必要があります(出力がタブ付きであると想定し、それ以外の場合はcut適切です)。

{your output} | cut -f1 '-d{tab}' | xargs -L 1 -I {} units -1t {}iB B | awk '{s+=$1}END{printf "%d\n",s}'

よく注意してください、精度が失われます。ユニットへの入力を補うこともできますがunits、最小限のディストリビューションで不足していることがわかりました!すべてを完全に制御できれば、私たち全員がこれを異なる方法で行うと思います。

2
VALUE=$1

for i in "g G m M k K"; do
        VALUE=${VALUE//[gG]/*1024m}
        VALUE=${VALUE//[mM]/*1024k}
        VALUE=${VALUE//[kK]/*1024}
done

[ ${VALUE//\*/} -gt 0 ] && echo VALUE=$((VALUE)) || echo "ERROR: size invalid, pls enter correct size"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.