给定文件的大小(以字节为单位),我想用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系统,则可以使用此功能.
Evi*_*ine 59
GNU Coreutils包含一个显然相当未知的小工具,称为numfmt数字转换,它可以满足您的需求:
$ numfmt --to=iec-i --suffix=B --format="%.3f" 4953205820
4.614GiB
Run Code Online (Sandbox Code Playgroud)
我认为这很适合你的需求,并不像其他答案那么大或者说是黑客.
如果您想要更强大的解决方案,请查看我的其他答案.
不要使用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
Run Code Online (Sandbox Code Playgroud)