#!/bin/bash
q=$(bc <<< "scale=2;$p*100")
head -n$q numbers.txt > secondcoordinate.txt
Это всего лишь часть скрипта, но я думаю, этого достаточно, чтобы прояснить мои намерения. p
— это переменная всего с двумя десятичными знаками, поэтому q
должна быть целым числом... Тем не менее, bc
показывает, например, 10.00
вместо 10
.
Как мне решить эту проблему?
решение1
С очевидными вещами этого сделать нельзя scale=0
из-за способа определения масштаба.
В документации косвенно объясняется, что деления на единицу достаточно, чтобы сбросить вывод до значения scale
, которое по умолчанию равно нулю:
выражение1 / выражение2Результатом выражения является частное двух выражений. Масштаб результата — это значение переменной scale.
p=12.34; echo "($p*100)" | bc
1234.00
p=12.34; echo "($p*100)/1" | bc
1234
Если ваша версия bc
не справляется с этим, передайте это по каналу sed
:
p=12.34; echo "($p*100)" | bc | sed -E -e 's!(\.[0-9]*[1-9])0*$!\1!' -e 's!(\.0*)$!!'
1234
Эта пара RE удалит конечные нули из десятичной части числа. Так, 3,00 сократится до 3, а 3,10 сократится до 3,1, но 300 останется неизменным.
В качестве альтернативы, используйте perl
и откажитесь от следующих средств bc
в первую очередь:
p=12.34; perl -e '$p = shift; print $p * 100, "\n"' "$p"
решение2
Вы можете использовать awk для расчета значений
bash-3.2$ p=0.01
bash-3.2$ q=$(awk -vp_val="$p" 'BEGIN{print p_val*100}')
bash-3.2$ echo $q
1
bash-3.2$ p=0.02
bash-3.2$ q=$(awk -vp_val="$p" 'BEGIN{print p_val*100}')
bash-3.2$ echo $q
2
bash-3.2$ p=0.022
bash-3.2$ q=$(awk -vp_val="$p" 'BEGIN{print p_val*100}')
bash-3.2$ echo $q
2.2
решение3
TL;DR
У вас есть много вариантов.До нашей эрыизвестно поведение, при котором scale=0
не всегда происходит то, что вы ожидаете, но есть много обходных путей. Вот лишь некоторые из них.
printf
Использоватьprintfчтобы ограничить вывод целыми числами.
$ printf "%g\n" $(echo '12.34 * 100' | bc)
1234
до нашей эры с делением
Если вы хотите придерживатьсяДо нашей эрымасштабирование, необходимо указать как масштаб нольиразделите на 1, чтобы сбросить масштаб. Это известное поведение, но я действительно не могу объяснить, почему оно происходит.
$ echo '12.34 * 100 / 1' | scale=0 bc
1234
сед
Просто удалите ненужные конечные символы.
$ echo '12.34 * 100' | bc | sed 's/\.00$//'
1234
Баш
Используйте раскрытие фигурных скобок, чтобы вернуть значение до десятичной точки.
$ p='12.34'; q=$(bc <<< "scale=2; $p*100"); echo ${q%%.00}
1234
решение4
Вот функция bash для удаления конечных нулей.
remove_trailing_zeroes()
{
declare -n n="$1"
# Prepend a 0 if number starts with a dot.
if [[ $n =~ ^[.] ]]; then
n="0$n"
fi
# Remove trailing zeroes
while [[ $n =~ [.].*0$ ]]; do
n="${n%0}"
done
# Remove trailing dot if any
if [[ $n =~ [.]$ ]]; then
n="${n%.}"
fi
}
Затем вы можете использовать его в вашем случае следующим образом:
q=$(bc <<< "scale=2;$p*100")
remove_trailing_zeroes q
head -n$q numbers.txt > secondcoordinate.txt