考虑到文件的大小(以字节为单位),我想用 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的评论。
答案 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)
不使用ls
和awk
来获取文件大小,而是使用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
如果你想要一个更简单,重量更轻的解决方案,请看看我的其他答案。