Zaczynam się uczyć pisania skryptów dla terminalu bash, ale nie mogę wymyślić, jak zapewnić prawidłowe działanie porównań. Używam skryptu:
echo "enter two numbers";
read a b;
echo "a=$a";
echo "b=$b";
if [ $a \> $b ];
then
echo "a is greater than b";
else
echo "b is greater than a";
fi;
Problem polega na tym, że porównuje liczbę od pierwszej cyfry, tzn. 9 jest większe niż 10, ale 1 jest większe niż 09.
Jak przekonwertować liczby na typ, aby dokonać prawdziwego porównania?
;
na końcu linii są zbędne. Nie robi nic złego, tylko strata klawiszy (chyba cieszyć wpisując średników).10#$number
taknumber=09; echo "$((10#$number))"
wyświetli,9
aecho $((number))
wygeneruje błąd „wartość zbyt duża dla podstawy”.>
operator wykonuje[
polecenie w celu porównania kolejności, w jakiej powinny być posortowane dwa ciągi, a nie kolejności, w jakiej byłyby sortowane jako liczby. Możesz znaleźć więcej informacji wman test
.Odpowiedzi:
W bash powinieneś sprawdzić w kontekście arytmetycznym :
W przypadku powłok POSIX, które nie obsługują
(())
, możesz użyć-lt
i-gt
.Możesz uzyskać pełną listę operatorów porównania za pomocą
help test
lubman test
.źródło
"$a" -gt "$b"
właściwa odpowiedź. Oto dobra lista operatora testowego: Konstrukcje testowe .test
jest to program taki, jaki jest[
. Więchelp test
daje informację o tym. Aby dowiedzieć się, jakich wbudowanych funkcji ([[
i((
) należy użyćhelp bash
i przejść do tej części.Prosty i prosty
Możesz sprawdzić ten ściąg jeśli chcesz więcej porównań liczbowych we wspaniałym świecie skryptów Bash.
Krótko mówiąc, liczby całkowite można porównać tylko z:
źródło
"$a"
i"$b"
nie są absolutnie konieczne, ale są dobrą praktyką. Nawiasy klamrowe nie robią tutaj nic przydatnego."
obowiązkowe czy[ $a -eq $b ]
też w porządku?Jest też jedna fajna rzecz, o której niektórzy mogą nie wiedzieć:
Ten kod wydrukuje najmniejszą liczbę spośród
a
ib
źródło
b
jeślia == b
.echo "The smaller number is $(( a < b ? a : b ))."
a < b
to nadal prawda, jeślia == b
. Nie znam wszystkich kaprysów warunkowych Basha, ale prawie na pewno są sytuacje, w których miałoby to znaczenie.a == b
, toa < b
ocenia na fałsz, dlatego zostanie wydrukowanyb
.W Bash wolę to robić, ponieważ odnosi się bardziej do operacji warunkowej, w przeciwieństwie do używania,
(( ))
która jest bardziej arytmetyczna.Chyba że robię takie skomplikowane rzeczy
Ale każdy ma swoje preferencje. Smutne jest to, że niektórzy ludzie narzucają swoje nieoficjalne standardy.
Aktualizacja:
Możesz także to zrobić:
Co pozwala ci dodać coś, co możesz zrobić
[[ ]]
oprócz arytmetyki.źródło
[[ ]]
wymusza kontekst arytmetyczny(( ))
, w którymN
traktowane jest tak, jakby to było$N
, ale nie sądzę, aby było to poprawne. Lub, jeśli nie taka była intencja, użycieN
iM
jest mylące.[[
poleceniemArg1
iArg2
jest oceniany jako wyrażenie arytmetyczne [...]”.NUMBER=0.0; while [[ "$NUMBER" -lt "1.0" ]]; do
i mówibash: [[: 0.0: syntax error: invalid arithmetic operator (error token is ".0")
Ten kod może również porównywać zmiennoprzecinkowe. Używa awk (nie jest to czysta bash), jednak nie powinno to stanowić problemu, ponieważ awk to standardowe polecenie POSIX, które najprawdopodobniej jest domyślnie dostarczane z twoim systemem operacyjnym.
Aby skrócić czas użycia, użyj tej funkcji:
źródło
bash
nie mogę ich odpowiednio porównać (spróbujif (( 18446744073692774399 < 8589934592 )); then echo 'integer overflow'; fi
).awk
działa jak urok (if awk "BEGIN {return_code=(18446744073692774399 > 8589934592) ? 0 : 1; exit} END {exit return_code}"; then echo 'no integer overflow'; fi
).Jeśli masz zmiennoprzecinkowe, możesz napisać funkcję, a następnie użyć jej np
źródło
Nawiasy (np.
[[ $a -gt $b ]]
Lub(( $a > $b ))
) nie są wystarczające, jeśli chcesz również używać liczb zmiennoprzecinkowych; zgłosiłby błąd składniowy. Jeśli chcesz porównać liczby zmiennoprzecinkowe lub liczby zmiennoprzecinkowe z liczbami całkowitymi, możesz użyć(( $(bc <<< "...") ))
.Na przykład,
Do instrukcji if można dołączyć więcej niż jedno porównanie. Na przykład,
Jest to przydatne, jeśli chcesz sprawdzić, czy zmienna liczbowa (liczba całkowita lub nie) mieści się w zakresie liczbowym.
źródło
if [ "$(bc <<<"$a > $b") == "1" ]; then echo "a is greater than b; fi
if [ $(bc <<<"$a > $b") == "1" ]; then echo "a is greater than b"; fi
? (Myślę, że twoje polecenie zostało źle napisane.) Jeśli tak, to też działa. Polecenie Bash Calculator (bc) to podstawowe polecenie kalkulatora. Więcej przykładów użycia można znaleźć tutaj i tutaj . Nie wiem jednak, dlaczego moje przykładowe polecenie nie działało dla ciebie.Rozwiązałem to, używając małej funkcji do konwersji ciągów wersji na zwykłe wartości całkowite, które można porównać:
To powoduje dwa ważne założenia:
Na przykład
Przykład testowania, czy
npm
polecenie spełnia minimalne wymagania ...źródło