Linux 人类可读格式的文件大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15854332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:39:47  来源:igfitidea点击:

File size in human readable format

linuxbash

提问by someguy

Given the size of a file in bytes, I want to format it with IEC (binary) prefixesto 3 significant figureswith trailing zeros, e.g. 1883954 becomes 1.80M.

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

Floating-point arithmetic isn't supported in bash, so I used awk instead. The problem is I don't how to keep the trailing zeros. Current solution:

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

(The files aren't that big so I don't have to consider bigger units.)

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

Edit: There's another problem with this. See Adrian Frühwirth's comment below.

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

采纳答案by Evi1M4chine

GNU Coreutilscontains an apparently rather unknown little tool called numfmtfor numeric conversion, that does what you need:

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

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

I think that suits your needs well, and isn't as large or hackish as the other answers.

我认为这很适合您的需求,并且不像其他答案那样庞大或笨拙。

If you want a more powerful solution, look at my other answer.

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

回答by P.P

If you don't mind using bcthen the following will help do floating point operations. scalecan changed as per your needs depending on many digits you want to print.

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

回答by MelBurslan

Is there any reason you are not using

你有什么理由不使用

ls -lh

command ? If you are on a Linux system which has been released in the last few years, you have this functionality.

命令 ?如果您使用的是最近几年发布的 Linux 系统,那么您就有此功能。

回答by Evi1M4chine

If you happen to have Qalculate!installed (which is awesome by the way), there's an easy trick:

如果你碰巧有Qalculate!安装(顺便说一句,这很棒),有一个简单的技巧:

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

Example:

例子:

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

It's a very very powerful tool to have in shell scripting, as it can even simplify formulas, solve for unknowns, and many many more things.

这是一个非常强大的 shell 脚本工具,因为它甚至可以简化公式、解决未知数等等。

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

If you want a simpler, less heavy-weight solution, look at my other answer.

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

回答by David J Merritt

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

回答by Nour-eddin

I know that it's a little late. But may someone find it useful.

我知道现在有点晚了。但也许有人会觉得它有用。

The answer is, simply, to use %.2finstead of %.3gin your script. (src)

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



Test:

测试:

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

The Output:

输出:

1.80M

回答by user208145

Instead of using lsand awkto get the file size, use stat -c %s filename.ext. It outputs only the number, with nothing else (at least on version 8.21). I can't use numfmtbecause it's an older version which doesn't appear to use the printf syntax with decimal precision. I instead use the script below. I use the last line to test if the script is being sourced. If it's not, I can call it directly on the command line.

不要使用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  | egrep -i '\-?[0-9]+') ] && echo 'Garbage data' && return 1

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

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

    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
}

[[ $_ == ##代码## ]] && getFriendlyFileSize