#!/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表达式的结果是两个表达式的商。结果的标度是变量标度的值。
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
长话短说
你有很多选择。公元前已知的行为scale=0
并不总是符合您的预期,但有很多解决方法。这里仅仅是少数。
打印函数
使用打印函数将输出限制为整数。
$ printf "%g\n" $(echo '12.34 * 100' | bc)
1234
BC与除法
如果你想坚持公元前缩放,您需要指定比例为零和除以 1 以重置刻度。这是已知的行为,但我真的无法解释其原因。
$ echo '12.34 * 100 / 1' | scale=0 bc
1234
sed
只需去掉不需要的尾随字符即可。
$ 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