文件大小为人类可读格式

som*_*guy 61 linux bash

给定文件的大小(以字节为单位),我想用IEC(二进制)前缀将其格式化为带有尾随零的3位有效数字,例如1883954变为1.80M.

bash不支持浮点运算,所以我改用了awk.问题是我不知道如何保持尾随零.当前解决方案

if [ $size -ge 1048576 ]
then
    size=$(awk 'BEGIN {printf "%.3g",'$size'/1048576}')M
elif [ $size -ge 1024 ]
then
    size=$(awk 'BEGIN {printf "%.3g",'$size'/1024}')K
fi
Run Code Online (Sandbox Code Playgroud)

(文件不是很大,所以我不必考虑更大的单位.)

编辑:这是另一个问题.请参阅下面的AdrianFrühwirth的评论.

Mel*_*lan 130

你有没有理由不使用

ls -lh
Run Code Online (Sandbox Code Playgroud)

命令?如果您使用的是过去几年发布的Linux系统,则可以使用此功能.

  • 从中解析大小是一个严重的混乱.不要那样做! (6认同)
  • 他希望输出的格式为3平方英尺,这就是原因. (3认同)
  • 因为它没有以我想要的格式提供它.就像我说的那样,对于3个有效尾随零的重要数字.我给出的例子 - 1883954 - 用ls变成1.8M,不是吗?(它可能与实现不同,但这与我的系统有关.) (2认同)
  • 根据这个答案(不是OP问题)`ls -lh ~/.bashrc | cut -d ' ' -f 5` >> `101k` (2认同)

Evi*_*ine 59

GNU Coreutils包含一个显然相当未知的小工具,称为numfmt数字转换,它可以满足您的需求:

$ numfmt --to=iec-i --suffix=B --format="%.3f" 4953205820
4.614GiB
Run Code Online (Sandbox Code Playgroud)

我认为这很适合你的需求,并不像其他答案那么大或者说是黑客.

如果您想要更强大的解决方案,请查看我的其他答案.

  • 您可以指定自8.24版以来的精度.`numfmt --to = iec-i --suffix = B --format ="%.3f"4953205820`输出4.614GiB (2认同)
  • @project:如果您不想在前缀中使用“i”,请使用“--to=iec”而不是“--to=iec-i”选项。 (2认同)

小智 11

ls -lah /path/to/your/file | awk -F " " {'print $5'}
Run Code Online (Sandbox Code Playgroud)


use*_*145 5

不要使用lsawk来获取文件大小,而是使用stat -c %s filename.ext. 它只输出数字,不输出任何其他内容(至少在 8.21 版本上)。我无法使用,numfmt因为它是旧版本,似乎没有使用具有十进制精度的 printf 语法。我改为使用下面的脚本。我使用最后一行来测试脚本是否已被获取。如果不是,我可以直接在命令行上调用它。

#!/bin/bash

function getFriendlyFileSize() {
    OUT='/dev/null'
    [ "$#" == 0 ] && echo 'No number given' && return 1
    [ ! $(echo $1 | egrep -i '\-?[0-9]+') ] && echo 'Garbage data' && return 1

    if [ "$1" == '' -o "$1" -lt 0 ] 2>$OUT
    then
            echo '0 B'
            return 1
    else
            FSIZE=$1
    fi

    [ "$2" == '' ] && DECPTS=1 || DECPTS=$2

    KB=1024
    MB=1048576
    GB=1073741824
    TB=1099511627776
    PB=1125899906842624
    EB=1152921504606846976
    LM=9223372036854775807 # bash comparison limit = 2^63-1 (signed int?)

    [ "$FSIZE" -le 0 ] 2>$OUT && echo "0 B" && return
    [ "$FSIZE" -lt $KB ] 2>$OUT && echo "$FSIZE B" && return
    [ "$FSIZE" -lt $MB ] 2>$OUT && echo "$(echo "scale=$DECPTS;$FSIZE/$KB"|bc) KB" && return
    [ "$FSIZE" -lt $GB ] 2>$OUT && echo "$(echo "scale=$DECPTS;$FSIZE/$MB"|bc) MB" && return
    [ "$FSIZE" -lt $TB ] 2>$OUT && echo "$(echo "scale=$DECPTS;$FSIZE/$GB"|bc) GB" && return
    [ "$FSIZE" -lt $PB ] 2>$OUT && echo "$(echo "scale=$DECPTS;$FSIZE/$TB"|bc) TB" && return
    [ "$FSIZE" -lt $EB ] 2>$OUT && echo "$(echo "scale=$DECPTS;$FSIZE/$PB"|bc) PB" && return
    [ "$FSIZE" -le $LM ] 2>$OUT && echo "$(echo "scale=$DECPTS;$FSIZE/$EB"|bc) EB" && return
    [ "$?" -ne '0' ] 2>$OUT && echo "Bad input" && return 1
}

[[ $_ == $0 ]] && getFriendlyFileSize $1 $2
Run Code Online (Sandbox Code Playgroud)