du, ls1 など、バイト数を人間の KiB MiB などに変換する標準ツールです。

du, ls1 など、バイト数を人間の KiB MiB などに変換する標準ツールです。

お持ちですか?標準ツール数値は1.00から1023.99?間を維持しながら、整数バイト数を人間が読める最大の単位サイズ数に変換します。

独自のbash/awkスクリプトがありますが、基準多くの/ほとんどのディストリビューションに見られるツール...より一般的に利用可能なツールであり、理想的には単純なコマンドライン引数を持ち、パイプ入力を受け入れることができます。

以下は、私が探している出力タイプのいくつかの例です。

    1    Byt  
  173.00 KiB  
   46.57 MiB  
    1.84 GiB  
   29.23 GiB  
  265.72 GiB  
    1.63 TiB  

ここにいるバイト人間スクリプト(上記の出力の場合)

awk -v pfix="$1" -v sfix="$2" 'BEGIN { 
      split( "Byt KiB MiB GiB TiB PiB", unit )
      uix = uct = length( unit )
      for( i=1; i<=uct; i++ ) val[i] = (2**(10*(i-1)))-1
   }{ if( int($1) == 0 ) uix = 1; else while( $1 < val[uix]+1 ) uix--
      num = $1 / (val[uix]+1)
      if( uix==1 ) n = "%5d   "; else n = "%8.2f"
      printf( "%s"n" %s%s\n", pfix, num, unit[uix], sfix ) 
   }'

修正する  修正版ですザイルズ彼の答えへのコメントで述べたように、スクリプト..(私の好きな外観に合わせて修正されました)。

awk 'function human(x) {
         s=" B   KiB MiB GiB TiB EiB PiB YiB ZiB"
         while (x>=1024 && length(s)>1) 
               {x/=1024; s=substr(s,5)}
         s=substr(s,1,4)
         xf=(s==" B  ")?"%5d   ":"%8.2f"
         return sprintf( xf"%s\n", x, s)
      }
      {gsub(/^[0-9]+/, human($1)); print}'

答え1

POSIXにはそのようなものはありませんが、最新のGNU coreutilsには数値フォーマッタがあります。numfmt少なくとも例の出力に近い。 GNU coreutils ≥8.24(2015年、サポート寿命が非常に長い最も古いバージョンを除くすべての非組み込みLinuxに存在):

$ numfmt --to=iec-i --suffix=B --format="%9.2f" 1 177152 48832200 1975684956
    1.00B
173.00KiB
 46.58MiB
  1.84GiB

多くの古いGNUツールはこのフォーマットを生成するかもしれません。GNUソートでは、数値を単位でソートできます。coreutils 7.5基準(2009年8月、ほぼすべての非埋め込みLinuxディストリビューションにあります)。


コードが少し複雑だと思います。以下はよりきれいなawkバージョンです(出力フォーマットはまったく同じではありません)。

awk '
    function human(x) {
        if (x<1000) {return x} else {x/=1024}
        s="kMGTEPZY";
        while (x>=1000 && length(s)>1)
            {x/=1024; s=substr(s,2)}
        return int(x+0.5) substr(s,1,1)
    }
    {sub(/^[0-9]+/, human($1)); print}'

より専門的な質問から再投稿)

答え2

v.で始まり、以下を含みます8.21coreutilsnumfmt:

numfmtさまざまな表現で数字を読み、必要に応じてフォーマットを再指定します。
最も一般的な使用法は、数値を数値に変換することです。 人類表現する。

例えば

printf %s\\n 5607598768908 | numfmt --to=iec-i
5.2 チタン

その他様々な例提供(フィルタリング、入出力処理など含む)ここ


またcoreutilsv。で始めると、8.24同様のnumfmtフィールド範囲仕様で複数のフィールドを処理でき、cutオプションを使用して出力精度設定をサポートします。--format

numfmt --to=iec-i --field=2,4 --format='%.3f' <<<'tx: 180000 rx: 2000000'
送信:175.782Ki受信:1.908Mi

答え3

これは bash のみのオプションであり、他の組み込みオプションも存在しないか、他のbcオプション、+ 10 進形式、および 2 進単位はありません。

# Converts bytes value to human-readable string [$1: bytes value]
bytesToHumanReadable() {
    local i=${1:-0} d="" s=0 S=("Bytes" "KiB" "MiB" "GiB" "TiB" "PiB" "EiB" "YiB" "ZiB")
    while ((i > 1024 && s < ${#S[@]}-1)); do
        printf -v d ".%02d" $((i % 1024 * 100 / 1024))
        i=$((i / 1024))
        s=$((s + 1))
    done
    echo "$i$d ${S[$s]}"
}

例:

$ bytesToHumanReadable 123456789
117.73 MiB

$ bytesToHumanReadable 1000000000000 # '1TB of storage'
931.32 GiB                           #  1TB of storage

$ bytesToHumanReadable 
0 Bytes

$ bytesToHumanReadable 9223372036854775807
7.99 EiB

すべてのBashバージョン(Windows用MSYSGitのBashを含む)でうまく動作するはずです。

答え4

これは、Peter.OがGillesのawkスクリプトを修正したバージョンに触発され、完全に書き直されたものです。

多様性:

  • 4文字より長い文字列を見つける必要がありますが、1文字より長い文字列を見つけるPeter.Oのバグを修正しました。このバグのため、彼のコードはZiBデバイスでは動作しません。
  • スペースで区切られた単位サイズの非常に見苦しいハードコーディングされた長いリストを削除します。
  • パディングを有効/無効にするコマンドラインスイッチが追加されました。
  • 基本1024(KiB)から基本1000(KB)表記に変換するためのコマンドラインスイッチが追加されました。
  • 使いやすい1つの機能ですべてを統合しましょう。
  • 私はそれをパブリックドメインに置き、広範な使用を歓迎します。

パスワード:

bytestohuman() {
    # converts a byte count to a human readable format in IEC binary notation (base-1024), rounded to two decimal places for anything larger than a byte. switchable to padded format and base-1000 if desired.
    local L_BYTES="${1:-0}"
    local L_PAD="${2:-no}"
    local L_BASE="${3:-1024}"
    BYTESTOHUMAN_RESULT=$(awk -v bytes="${L_BYTES}" -v pad="${L_PAD}" -v base="${L_BASE}" 'function human(x, pad, base) {
         if(base!=1024)base=1000
         basesuf=(base==1024)?"iB":"B"

         s="BKMGTEPYZ"
         while (x>=base && length(s)>1)
               {x/=base; s=substr(s,2)}
         s=substr(s,1,1)

         xf=(pad=="yes") ? ((s=="B")?"%5d   ":"%8.2f") : ((s=="B")?"%d":"%.2f")
         s=(s!="B") ? (s basesuf) : ((pad=="no") ? s : ((basesuf=="iB")?(s "  "):(s " ")))

         return sprintf( (xf " %s\n"), x, s)
      }
      BEGIN{print human(bytes, pad, base)}')
    return $?
}

テストケース(出力を見たい場合):

bytestohuman 1; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 500; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1023; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1024; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1500; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000000; echo "${BYTESTOHUMAN_RESULT}.";

bytestohuman 1 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 500 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1023 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1024 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1500 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000000 no 1000; echo "${BYTESTOHUMAN_RESULT}.";

bytestohuman 1 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 500 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1023 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1024 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1500 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000 yes; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000000 yes; echo "${BYTESTOHUMAN_RESULT}.";

bytestohuman 1 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 500 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1023 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1024 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 1500 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";
bytestohuman 150000000000000000000 yes 1000; echo "${BYTESTOHUMAN_RESULT}.";

楽しむ!

関連情報