#!/bin/bash
q=$(bc <<< "scale=2;$p*100")
head -n$q numbers.txt > secondcoordinate.txt
Das ist nur ein Teil des Skripts, aber ich denke, es reicht aus, um meine Absichten zu verdeutlichen. p
ist eine Variable mit nur zwei Dezimalstellen, q
sollte also eine Ganzzahl sein … Trotzdem bc
wird beispielsweise anstelle 10.00
von angezeigt 10
.
Wie kann ich das lösen?
Antwort1
scale=0
Aufgrund der Art und Weise, wie der Maßstab bestimmt wird, ist dies mit dem Offensichtlichen nicht möglich .
In der Dokumentation wird indirekt erklärt, dass eine Division durch eins ausreicht, um die Ausgabe auf den Wert von zurückzusetzen scale
, der standardmäßig Null ist:
Ausdruck1 / Ausdruck2Das Ergebnis des Ausdrucks ist der Quotient der beiden Ausdrücke. Die Skala des Ergebnisses ist der Wert der Variablen Skala.
p=12.34; echo "($p*100)" | bc
1234.00
p=12.34; echo "($p*100)/1" | bc
1234
Wenn Ihre Version bc
dies nicht handhaben kann, leiten Sie es sed
stattdessen weiter:
p=12.34; echo "($p*100)" | bc | sed -E -e 's!(\.[0-9]*[1-9])0*$!\1!' -e 's!(\.0*)$!!'
1234
Dieses RE-Paar entfernt nachfolgende Nullen aus dem Dezimalteil einer Zahl. So wird 3,00 auf 3 reduziert und 3,10 auf 3,1, aber 300 bleibt unverändert.
Alternativ verwenden und von vornherein perl
darauf verzichten :bc
p=12.34; perl -e '$p = shift; print $p * 100, "\n"' "$p"
Antwort2
Sie können awk verwenden, um die Werte zu berechnen
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
Antwort3
Kurz zusammengefasst
Sie haben viele Möglichkeiten.v. Chr.weist bekanntes Verhalten auf, bei dem scale=0
nicht immer das erwartete Ergebnis erzielt wird, aber es gibt viele Workarounds. Hier sind nur einige davon.
druckenf
Verwendendruckenfum Ihre Ausgabe auf ganze Zahlen zu beschränken.
$ printf "%g\n" $(echo '12.34 * 100' | bc)
1234
BC mit Division
Wenn Sie dabei bleiben möchtenv. Chr.Skalierung müssen Sie sowohl einen Maßstab von Null angebenUnddurch 1 teilen, um den Maßstab zurückzusetzen. Das ist ein bekanntes Verhalten, aber ich kann nicht wirklich erklären, warum.
$ echo '12.34 * 100 / 1' | scale=0 bc
1234
sed
Entfernen Sie einfach die unerwünschten nachstehenden Zeichen.
$ echo '12.34 * 100' | bc | sed 's/\.00$//'
1234
Schlag
Verwenden Sie eine Klammererweiterung, um den Wert vor der Dezimalstelle zurückzugeben.
$ p='12.34'; q=$(bc <<< "scale=2; $p*100"); echo ${q%%.00}
1234
Antwort4
Hier ist eine Bash-Funktion zum Entfernen nachstehender Nullen.
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
}
Du kannst es dann für deinen Fall folgendermaßen verwenden:
q=$(bc <<< "scale=2;$p*100")
remove_trailing_zeroes q
head -n$q numbers.txt > secondcoordinate.txt