基本電卓の出力を変数に入れることはできません。 bashのバイトをMBにフォーマットします。

基本電卓の出力を変数に入れることはできません。 bashのバイトをMBにフォーマットします。

私のWi-Fiデバイスのデータ使用量をトップバーに表示したいです。次のように、カールを使用してデータ使用量をバイト単位で取得できます。

$bytes=(curl -d "Page=GetWANInfo" -X POST http://jiofi.local.html/cgi-bin/qcmap_web_cgi -s| jq -r .total_data_used)

今のように大きな数字が出てきます。411982397これをMBに変換して、次のように表示したいと思います。411.9 MB

しかし、このように大きな数字をどのようにフォーマットできるかわかりません。

私はbcそれをMBに変換しようとしました。echo $bytes / 1000000 | bc

しかし、変数に入れることができず、エラーが発生します。

$ total=($bytes / 1000000 | bc)
bash: syntax error near unexpected token `|'
$ total=$($bytes / 1000000 | bc)
411982397: command not found
$ echo "$bytes / 1000000" | bc
411
$ total=$("$bytes / 1000000" | bc)
bash: 411982397 / 1000000: No such file or directory

私の考えは、出力を変数に入れることです。echo $total MB

この問題を解決するためのより良い方法は何ですか?また、このコマンドを数秒ごとに実行する必要があるため、CPUを使いやすくすることができるこの問題に対する効率的なソリューションが必要です。

答え1

jq分割することができます:

$ echo '{"total_data_used":411982397}' | jq -r '.total_data_used/1e6|tostring + "MB"'
411.982397MB

特にbashを使用する必要がない場合、ほとんどの最新のシェル(少なくともzsh、ksh93、yash、fish)は自分でこれを行うこともできます。

zshから:

printf -v total %gMB $(( bytes / 1_000_000. ))

.浮動小数点演算を強制することに注意してください。それも使用できます1e6)。

ksh93には、printf1000ベースのユニットと1024ベースのユニットの両方を使用して、kMGTPEサフィックスを含む人が読める形式に変換する機能も組み込まれています。

$ printf '%#dB\n' bytes
412MB
$ printf '%#iB\n' bytes
393MiB

特に bash で 10 の累乗で割る特別な場合には、これを整数にprintf追加し、 、 、 、 (または大文字変換)の引数として使用して使用できます。e-6%e%f%g%a

printf -v total %gMB "${bytes}e-6"

デフォルトの精度は有効数字6桁ですが、必要に応じて%g精度をたとえば12桁に変更できます。 (少なくともbashとzshでは)ロケールの10進基本文字が尊重されます%.12gprintfたとえば、英語ロケールでは411.982MB、フランス語/ドイツ語ロケールでは411,982MBを取得します。

除算を実行するには、出力するコマンドの出力をパイピングするか(通常はこれに使用されます)、ドキュメントhere(standard)またはhere - string(zshから)を使用してbc標準入力に式を提供する必要があります。他の多くのシェルで見つかりました)コマンド置換を使用してパイプを介して出力を取得します(たとえば、変数に保存)。printfshtotal

scaleただし、分割するときは、下数の後に数桁を数えるように特別な変数を設定する必要があります(-lオプションを使用しない限り、デフォルトは0、この場合は20です)。だから:

total=$(
  printf 'scale=2\n%d / 1000000\n' "$bytes" | bc
)

または:

total=$(
  bc << EOF
scale=2
$bytes / 1000000
EOF
)

別の方法は、浮動小数点演算を実行し、数値を一意の形式にフォーマットすることができることbcです。awkprintf

total=$(
  jq... | awk '{printf "%gMB", $0 / 1e6}'
)

1echo度は一般的に使用されますが、移植性がなく信頼できないAPIがあるため、通常の場合はランダムなデータを出力しないことをお勧めします。

答え2

私はあなたが探していると思いますtotal=$(echo "$bytes / 1000000 " | bc)

関連情報