#!/bin/bash
q=$(bc <<< "scale=2;$p*100")
head -n$q numbers.txt > secondcoordinate.txt
これはスクリプトの一部に過ぎませんが、私の意図を明確にするには十分だと思います。p
は小数点が 2 桁しかない変数なので、q
整数である必要があります... ただし、 は、 bc
たとえば10.00
の代わりにを表示します10
。
これをどうすれば解決できますか?
答え1
scale=0
スケールの決定方法により、明らかな場合はこれを行うことはできません。
scale
ドキュメントでは、1 で割るだけで出力を の値(デフォルトでは 0)にリセットできることを間接的に説明しています。
式1 / 式2式の結果は 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
要約
選択肢はたくさんあります。紀元前必ずしも期待どおりに動作しないという既知の動作がありますscale=0
が、回避策は多数あります。ここではいくつかを紹介します。
プリント
使用プリント出力を整数に制限します。
$ printf "%g\n" $(echo '12.34 * 100' | bc)
1234
紀元前と除算
もしあなたが紀元前スケーリングでは、スケールをゼロと指定する必要がありますそしてスケールをリセットするには 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