Размер файла в человекообразном формате
Учитывая размер файла в байтах, я хочу отформатировать его с префиксами 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
(Файлы не такие большие, поэтому мне не нужно рассматривать большие единицы.)
Изменение: Есть еще одна проблема с этим. См. Комментарий Адриана Фрювирта ниже.
Ответы
Ответ 1
GNU Coreutils содержит, по-видимому, довольно неизвестный небольшой инструмент numfmt
для преобразования numfmt
, который делает то, что вам нужно:
$ numfmt --to=iec-i --suffix=B --format="%.3f" 4953205820
4.614GiB
Я думаю, что это хорошо соответствует вашим потребностям, и не так велико или хакерски, как другие ответы.
Если вы хотите более мощное решение, посмотрите на мой другой ответ.
Ответ 2
Есть ли причина, по которой вы не используете
ls -lh
команда? Если вы находитесь в системе Linux, выпущенной за последние несколько лет, у вас есть эта функция.
Ответ 3
ls -lah /path/to/your/file | awk -F " " {'print $5'}
Ответ 4
Я знаю, что это немного поздно. Но может кто-то сочтет это полезным.
Ответ заключается в том, чтобы просто использовать %.2f
вместо %.3g
в script. (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
Ответ 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
Ответ 6
Вместо того, чтобы использовать ls
и awk
для получения размера файла, используйте stat -c %s filename.ext
. Он выводит только номер, и ничего больше (по крайней мере, на версии 8.21). Я не могу использовать numfmt
, потому что это более старая версия, которая не использует синтаксис printf с десятичной точностью. Вместо этого я использую script ниже. Я использую последнюю строку для проверки наличия источника script. Если это не так, я могу вызвать его непосредственно в командной строке.
#!/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
Ответ 7
Если у вас установлено Qalculate! (что, кстати, удивительно)
Theres легкий трюк:
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
Если вы хотите более простое и менее тяжелое решение, посмотрите на мой другой ответ.
Ответ 8
Предпочтительное решение
man stat
* Пример использования " читабельного формата " в stat: *
stat %A custom_file.txt
ура