Размер файла в удобочитаемом формате



дан размер файла в байтах, я хочу отформатировать его с IEC (двоичные) префиксы до 3 значащие цифры С замыкающими нулями, например 1883954 становится 1.80 м.



арифметика с плавающей запятой не поддерживается в 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


(файлы не такие большие, поэтому мне не нужно рассматривать больше единицы.)



Edit: есть еще одна проблема с этим. Увидеть Эдриан Frühwirth комментарий ниже.

495   7  

7 ответов:

Coreutils содержит, по-видимому, довольно неизвестный маленький инструмент под названием numfmt для числового преобразования, что делает то, что вам нужно:

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

Я думаю, что хорошо подходит для ваших нужд и не так велик или хакер, как другие ответы.

Если вы хотите более мощное решение, посмотрите на мой другой ответ.

есть ли причина, по которой вы не используете

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

Я знаю, что уже немного поздно. Но может кто-то найдет это полезным.

ответ, просто, чтобы использовать %.2f вместо %.3g в свой сценарий. ( src)


Если вы не возражаете против использования 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

вместо 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  | 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  

Если у вас есть Qalculate! установлен (который является удивительным, кстати), есть простой трюк:

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

пример:

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

Это очень мощный инструмент, чтобы иметь в оболочке сценариев, как это может даже упростить формулы, решить для неизвестных, и многое другое.

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

Если вы хотите более простое, менее тяжелое решение, посмотрите на мой другой ответ.

Comments

    Ничего не найдено.