文件大小为人类可读格式

时间:2013-04-06 18:10:28

标签: linux bash

考虑到文件的大小(以字节为单位),我想用 IEC (binary) prefixes 格式化为 3 significant figures并使用尾随零,例如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

(文件不是那么大,所以我不必考虑更大的单位。)

编辑:这还有另外一个问题。请参阅下面的AdrianFrühwirth的评论。

8 个答案:

答案 0 :(得分:128)

你有没有理由不使用

ls -lh

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

答案 1 :(得分:55)

GNU Coreutils包含一个名为numfmt的明显不为人知的小工具,用于数字转换,可以满足您的需求:

$ numfmt --to=iec-i --suffix=B --format="%.3f" 4953205820
4.614GiB

我认为这很适合您的需求,并不像其他答案那么大或不那么苛刻。

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

答案 2 :(得分:9)

ls -lah /path/to/your/file | awk -F " " {'print $5'}

答案 3 :(得分:3)

我知道这有点晚了。但也许有人觉得它很有用。

答案很简单,就是在脚本中使用%.2f而不是%.3g。 (src

测试:

#!/bin/bash

size=1883954

if [ $size -ge 1048576 ]
then
    size=$(awk 'BEGIN {printf "%.2f",'$size'/1048576}')M
elif [ $size -ge 1024 ]
then
    size=$(awk 'BEGIN {printf "%.2f",'$size'/1024}')K
fi

echo $size

输出:

1.80M

答案 4 :(得分:2)

如果您不介意使用bc,则以下内容将有助于执行浮点运算。 scale可根据您的需要进行更改,具体取决于您要打印的多个数字。

size=1883954

if [ $size -ge 1048576 ]
then
    size=$(echo "scale=2;$size/1048576"| bc)M
elif [ $size -ge 1024 ]
then
    size=$(echo "scale=2;$size/1024" | bc)K
fi

echo $size

答案 5 :(得分:1)

不使用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

答案 6 :(得分:1)

首选解决方案:

man stat

在统计信息中获取“ 人类可读格式 ”的示例:

stat %A custom_file.txt

  

欢呼

答案 7 :(得分:0)

如果您碰巧安装了Qalculate!(顺便说一下这很棒), 有一个简单的伎俩:

human_readable="$( qalc -t set "precision $precision" "${in_bytes}B" )"

示例:

$ qalc -t -set "precision 3" 5264334820B
5.26 GB

这是一个非常强大的shell脚本工具,因为它甚至可以简化公式,解决未知问题以及更多的事情。

$ qalc -t "e^(i*x)=-1"
x = 3.1415927

如果你想要一个更简单,重量更轻的解决方案,请看看我的其他答案。