Я очень стараюсь сравнить два числа с плавающей точкой в скрипте bash. Я должен к переменным, например
let num1=3.17648e-22
let num2=1.5
Теперь я просто хочу сделать простое сравнение этих двух чисел:
st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
К сожалению, у меня есть некоторые проблемы с правильной обработкой num1, который может быть «электронного формата». :(
Любая помощь, советы приветствуются!
Ответы:
Удобнее
Это может быть сделано более удобно, используя числовой контекст Bash:
объяснение
Передача через основную команду калькулятора
bc
возвращает либо 1, либо 0.Опция
-l
эквивалентна--mathlib
; загружает стандартную математическую библиотеку.Заключив все выражение в двойные скобки,
(( ))
вы переведете эти значения соответственно в true или false.Пожалуйста, убедитесь, что
bc
базовый пакет калькулятора установлен.Это одинаково работает для поплавков в научном формате, при условии, что используется заглавная буква
E
, напримерnum1=3.44E6
источник
bc
калькулятор.0: not found
с заявлениемif (( $(echo "$TOP_PROCESS_PERCENTAGE > $THRESHOLD" | bc -l) )); then
.bc
в кавычки или$()
затем в(( ))
... то есть(( $(bc -l<<<"$a>$b") ))
и нет(( bc -l<<<"$a>$b" ))
.E
, и все синтаксические ошибки исчезнут.bash обрабатывает только целочисленную математику, но вы можете использовать
bc
команду следующим образом:Обратите внимание, что знак экспоненты должен быть в верхнем регистре
источник
bc
инструмент, и это то, что я бы порекомендовал любому программисту BASH. BASH - это язык без шрифта. Да, он может выполнять целочисленную арифметику, но для плавающей запятой вы должны использовать какой-то внешний инструмент. BC - лучший, потому что для этого он и создан.Лучше использовать
awk
для нецелой математики. Вы можете использовать эту функцию утилиты bash:И назовите это как:
источник
awk
иbc
в сценариях оболочки является стандартной практикой с древних времен, я бы сказал, что некоторые функции никогда не добавлялись в оболочки, потому что они доступны в awk, bc и других инструментах Unix. Нет необходимости в чистоте в сценариях оболочки.exit
Awk передавал результат обратно в оболочку правильным, машиночитаемым способом.if awk -v n1="123.456" -v n2="3.14159e17" 'BEGIN { exit (n1 <= n2) }' /dev/null; then echo bigger; else echo not; fi
... хотя обратите внимание, как условие инвертируется (состояние выхода 0 означает успех для оболочки).python
. Выperl
установили по умолчанию во многих системах Linux / Unix .. дажеphp
такжеawk
решение является более надежным в моем случае, чем решение,bc
которое возвращает неправильные результаты по причине, которую я не получил.Решение Pure Bash для сравнения поплавков без экспоненциальной записи, начальных или конечных нулей:
Порядок логических операторов имеет значение . Целочисленные части сравниваются как числа, а дробные части преднамеренно сравниваются как строки. С помощью этого метода переменные делятся на целые и дробные части .
Не будет сравнивать числа с плавающей точкой (без точки).
источник
Вы можете использовать awk в сочетании с условием bash if, awk выведет 1 или 0, и они будут интерпретированы выражением if со значением true или false .
источник
if (( $(echo $d1 $d2 | awk '{if ($1 > $2) print 1;}') )); then echo "yes"; else echo "no"; fi
будьте осторожны при сравнении чисел, являющихся версиями пакета, например, проверка, если grep 2.20 больше, чем версия 2.6:
Я решил такую проблему с такой функцией shell / awk:
источник
dpkg --compare-versions
часто бывает полезно. Он имеет полную логику для сравнения встроенных в него версий пакетов Debian, которые сложнее, чем простоx.y
.Конечно, если вам не нужна действительно арифметика с плавающей точкой, а только арифметика, например, в значениях доллара, где всегда есть ровно две десятичных цифры, вы можете просто отбросить точку (эффективно умножая на 100) и сравнить полученные целые числа.
Это, очевидно, требует, чтобы вы были уверены, что оба значения имеют одинаковое количество десятичных знаков.
источник
Я использовал ответы отсюда и поместил их в функцию, вы можете использовать это так:
Однажды позвонив,
echo $result
будет1
в этом случае, иначе0
.Функция:
Или версия с выводом отладки:
Просто сохраните функцию в отдельном
.sh
файле и включите ее так:источник
Я публиковал это как ответ на https://stackoverflow.com/a/56415379/1745001 когда он был закрыт, как дубликат этого вопроса, так что здесь это так, как и здесь:
Для простоты и ясности просто используйте awk для вычислений, поскольку это стандартный инструмент UNIX, и с такой же вероятностью он присутствует как bc, и с ним намного проще работать синтаксически.
По этому вопросу:
и для этого другого вопроса, который был закрыт как дубликат этого:
источник
awk
и подобные инструменты (я смотрю на васsed
...) должны быть отправлены на свалку старых проектов с кодом, который все слишком боятся трогать, поскольку он был написан на языке, никогда не читающем.Или вы сравнительно редкий проект, которому нужно расставить приоритеты оптимизации использования процессора над оптимизацией обслуживания кода ... в таком случае продолжайте.
Если нет, то почему бы просто не использовать что-то читаемое и явное, например
python
? Ваши коллеги по программированию и будущие я будут вам благодарны. Вы можете использоватьpython
inline с bash, как и все остальные.источник
not(...)
вместо0 if ... else 1
awk '${print $5}' ptpd_log_file | perl -ne '$_ > 0.000100 && print' > /tmp/outfile
, Очень просто. Каждый язык имеет свое место.python -c "import sys; sys.exit(0 if float($num1) < float($num2) else 1)"
простоawk "BEGIN{exit ($num1 > $num2 ? 0 : 1)}"
.Этот скрипт может помочь, когда я проверяю, установлена ли установленная
grails
версия больше минимально необходимой. Надеюсь, поможет.источник
источник
пожалуйста, проверьте ниже отредактированный код: -
это работает хорошо.
источник
Решение, поддерживающее все возможные нотации, включая научную нотацию с показателем в верхнем и нижнем регистре (например,
12.00e4
):источник
Используйте оболочку korn, в bash вам, возможно, придется сравнить десятичную часть отдельно
источник
Используя bashj ( https://sourceforge.net/projects/bashj/ ), мутанта bash с поддержкой java, вы просто пишете (и его легко читать):
Конечно, гибрид bashj / java предлагает гораздо больше ...
источник
Как насчет этого? = D
источник
exit 0
сообщать правду иexit 1
возвращать ложь; тогда вы можете упростить до удивительно элегантногоif awk 'BEGIN { exit (ARGV[1] >= ARGV[2]) ? 0 : 1 }' "$VAL_TO_CHECK" 1; then
... (еще более элегантного, если вы инкапсулируете скрипт Awk в функцию оболочки).