1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

bashで数字を読みやすい単位で表示する

Last updated at Posted at 2021-01-12

数字を 123k とか 123.45M とか、大きさに応じて読みやすい(human-readableな)単位で変換する関数。

ノーマル実装

convert_unit() {
  local RESULT=$1

  if [[ `echo -n ${RESULT%%.*}` -lt 1000 ]]; then
    echo -n "${RESULT}"
    return
  fi

  for U in k M G T P; do
    RESULT=`echo "scale=2; ${RESULT} / 1000" | bc`
    [[ `echo -n ${RESULT%%.*}` -lt 1000 ]] && break
  done
  printf "%.2f%s" "${RESULT}" ${U:-P}
}

普通にループで1000で割り続ける方法。
とりあえず、ペタまで対応しました。

実行結果
while read VAL; do
  echo "$VAL => `convert_unit $VAL`"
done < <(cat <<!!!
1
999
4321
7654321
1987654321
4321987654321
7654321987654321
1987654321987654321
!!!
)

# 1 => 1
# 999 => 999
# 4321 => 4.32k
# 7654321 => 7.65M
# 1987654321 => 1.98G
# 4321987654321 => 4.32T
# 7654321987654321 => 7.65P
# 1987654321987654321 => 1987.65P

シェル芸的実装

と、ここまで書いてシェル芸的な実装を思いついた。

convert_unit() {
  local TMP=`mktemp -u`
  truncate -s "$1" $TMP
  ls -lh --si $TMP | awk '{print $5}'
  [[ -f $TMP ]] && rm -f $TMP
}

指定されたサイズのスパースファイルを作成して、lsコマンドに出力させる方法。

ちょっとトリッキーですが。

実行結果
1 => 1
999 => 999
4321 => 4.4k
7654321 => 7.7M
1987654321 => 2.0G
4321987654321 => 4.4T
7654321987654321 => 7.7P
1987654321987654321 => 2.0E

ls の場合は小数点以下を切り上げにするようなので、出力が若干異なります。

mktemp コマンドで非推奨の -u オプションを使用しているので、厳密にいえば名前が競合する可能性があるので、こちらはあくまでネタとしてどうぞ。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?