Проблема связана с https://github.com/docker/docker/issues/8539, которая решена в докере 1.10 или более поздней версии. Была некоторая проблема с драйвером журнала Docker, которая привела к проблемам с буфером, особенно для сброса STDOUT контейнера.
Ваш вопрос немного двусмыслен. Вы говорите: «…Нужно сохранить все эти 0…». Другие рассказали вам, как получить вывод с восемью десятичными цифрами. Но хотите ли вы динамически определить, сколько десятичных цифр входные значения a
и b
уже имеют (, чтобы вы могли выводить c
с той же точностью )?
Вы можете сделать это внутри bash:
a_digits=0
if [[ $a =~ \.([0-9]*)$ ]]
then
a_digits="${#BASH_REMATCH[1]}"
fi
b_digits=0
if [[ $b =~ \.([0-9]*)$ ]]
then
b_digits="${#BASH_REMATCH[1]}"
fi
=~
сравнивает строку с регулярным выражением. Регулярное выражение \.([0-9]*)$
соответствует.
за которым следует последовательность цифр в конце строки, с последовательностью цифр в группе. BASH_REMATCH
— это массив, содержащий совпадение для всего регулярного выражения. и группы захвата (, если таковые имеются ). Таким образом, если a
– это 3.1416
, BASH_REMATCH[1]
– это 1416
. Затем a_digits
получает его длину, которая равна 4
.
Если у вас нет bash, вы можете сделать то же самое командой expr
:
a_digits=$( expr length '(' "$a" : '.*\.\([0-9]*\)$' ')' )
b_digits=$( expr length '(' "$b" : '.*\.\([0-9]*\)$' ')' )
что является точно такой же логикой.
Затем можно получить большее (максимальное )значение:
if [ "$a_digits" -gt "$b_digits" ]
then
digits="$a_digits"
else
digits="$b_digits"
fi
или наоборот, чтобы получить меньшее (минимальное )значение.
Затем вы можете использовать эту динамически определяемую точность в других решениях:
printf "%0.${digits}f\n" "$c"
или
printf '%0.*f\n' "$digits" "$c"
или
…scale=$digits; …
Просто используйте awk:
$ cat tst.sh
#!/bin/env bash
hypothenuse() {
awk -v a="$1" -v b="$2" 'BEGIN {
printf "This is a %0.8f and b %0.8f\n", a, b
c = sqrt(a^2 + b^2)
printf "This is c %0.8f\n", c
}'
}
hypothenuse "$@"
$./tst.sh 0 0
This is a 0.00000000 and b 0.00000000
This is c 0.00000000
$./tst.sh 17.12 23.567
This is a 17.12000000 and b 23.56700000
This is c 29.12898709
Таким образом, вы можете внедрить форматирование, используяprintf
:
printf "%0.8f" ${x}
Пример:
x=3
printf "%0.8f\n" ${x}
3.00000000
Примечание. Вывод:printf
зависит от ваших региональных настроек.
В bc решение состоит в делении на 1:
$ bc -l <<<"scale=8; x=25*20; x"
500
$ bc -l <<<"scale=8; x=25*20; x/1"
500.00000000
Итак, ваш сценарий может быть таким:
hypothenuse () {
local a b c x y
a=${1}; b=${2}
echo "This is a ${a} and b ${b}"
x=$(echo "scale=8; $a^2/1" | bc -l)
y=$(echo "scale=8; $b^2/1" | bc -l)
echo "This is x ${x} and y ${y}"
# local sum=`awk -v k=$x -v k=$y 'BEGIN {print (k + l)}'`
# echo "This is sum ${sum}"
c=$(echo "scale=8; sqrt($a^2 + $b^2)/1" | bc -l)
echo "This is c ${c}"
}
Я настоятельно рекомендую вам использовать $(…)
вместо `…`
.
Но даже это не работает со значениями 0.
Лучшее решение состоит в том, чтобы масштаб bc был равен 20 (от bc -l ), выполнить всю необходимую математику одним вызовом bc, а затем отформатировать вывод в соответствии с требованиями с помощью printf
. Да, printf
может форматировать числа с плавающей запятой.
Предполагая удар
hypothenuse () { local a b c x y
a=${1:-0} b=${2:-0}
read -d '' x y c < <(
bc -l <<<"a=$a; b=$b; x=a^2; y=b^2; c=sqrt(x+y); x;y;c"
)
printf 'This is a %14.8f and b %14.8f\n' "$a" "$b"
printf 'This is x %14.8f and y %14.8f\n' "$x" "$y"
printf 'This is c %14.8f \n' "$c"
}