#!/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