文件大小以人们可读的格式

给定一个文件大小的字节数,我想用IEC(二进制)前缀格式化为3个有效数字 ,后缀为零 ,例如1883954变为1.80M。

bash不支持浮点运算,所以我用awk代替。 问题是我不怎么保留尾随零。 当前解决scheme

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的评论。

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

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

我觉得你的需求很好,而且不像其他答案那么大或者不讨人喜欢。

如果你想要一个更强大的解决scheme,看看我的其他答案。

有什么原因,你没有使用

 ls -lh 

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

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

如果你不介意使用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 

我知道这有点晚了。 但是可能有人觉得它有用。

答案只不过是在脚本中使用%.2f而不是%.3g 。 ( src )


testing:

 #!/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 

使用stat -c %s filename.ext ,而不是使用lsawk来获取文件大小。 它只输出数字,没有别的(至less在版本8.21上)。 我不能使用numfmt因为它是一个旧版本,它似乎没有使用小数精度的printf语法。 我改用下面的脚本。 我使用最后一行来testing脚本是否来源。 如果不是,我可以直接在命令行上调用它。

 #!/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 

如果你碰巧有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 

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