Я хочу сделать цикл для Bash с 0,02 в качестве приращений я пытался
for ((i=4.00;i<5.42;i+=0.02))
do
commands
done
но это не сработало.
bash
for
floating-point
Mehrshad
источник
источник
bc
, но остановка на 4.52 может быть хитрой. используйте предложение @roaima, используйте вспомогательную переменную с шагом 2 и используйтеi=$(echo $tmp_var / 100 | bc)
Ответы:
Чтение справочной
bash
страницы дает следующую информацию:и тогда мы получим этот раздел
Таким образом, ясно видно, что вы не можете использовать
for
цикл с нецелыми значениями.Одним из решений может быть простое умножение всех ваших компонентов цикла на 100, что позволяет использовать их там, где вы позже будете их использовать, например:
источник
k=400;k<542;k+=2
поскольку оно позволяет избежать потенциальных арифметических проблем с плавающей запятой.bc
), разветвляете процесс, создаете временный файл (для строки here), выполняетеbc
в нем (что подразумевает загрузку исполняемых и разделяемых библиотек и инициализирую их), дождемся его и приведем в порядок. Запускатьbc
один раз, чтобы сделать цикл, будет намного эффективнее.i=$(bc <<< "scale...")
илиi=$(echo "scale..." | bc)
<<<
взялась),bash
иksh
. Обратите внимание, что переключение на другую оболочку, чемbash
в любом случае, даст вам большее повышение производительности, чем использование другого синтаксиса.<<<
(ЗШ, МКШ, ksh93, йаш) также поддерживает арифметику с плавающей запятой (zsh
,ksh93
,yash
)).Избегайте петель в ракушках.
Если вы хотите сделать арифметику, используйте
awk
илиbc
:Или
Обратите внимание, что
awk
(вопрекиbc
) работает с вашими процессорами представленияdouble
чисел с плавающей запятой (вероятно, типа IEEE 754 ). В результате, поскольку эти числа являются двоичными приближениями этих десятичных чисел, у вас могут быть некоторые сюрпризы:Если вы добавите,
OFMT="%.17g"
вы увидите причину пропажи0.3
:bc
имеет произвольную точность, поэтому не имеет такой проблемы.Обратите внимание, что по умолчанию (если вы не изменяете выходной формат с помощью
OFMT
или не используетеprintf
явные спецификации формата),awk
используется%.6g
для отображения чисел с плавающей запятой, поэтому переключился бы на 1e6 и выше для чисел с плавающей запятой свыше 1 000 000 и урезал дробную часть для больших чисел (100000.02 будет отображаться как 100000).Если вам действительно нужно использовать цикл оболочки, так как , например , вы хотите запустить определенные команды для каждой итерации этого цикла, либо использовать оболочку с плавающей запятой арифметической поддержки , как
zsh
,yash
илиksh93
или создать список значений с помощью одной команды , как указаны выше (или,seq
если доступно) и переберите его вывод.Подобно:
Или:
если вы не увеличите пределы чисел с плавающей запятой вашего процессора, то
seq
ошибки, возникшие из-за аппроксимации с плавающей запятой, будут обрабатываться более изящно, чемawk
вышеприведенная версия.Если у вас нет
seq
(команда GNU), вы можете сделать более надежную функцию как:Это будет работать лучше для таких вещей, как
seq 100000000001 0.000000001 100000000001.000000005
. Однако обратите внимание, что наличие чисел с произвольно высокой точностью мало поможет, если мы собираемся передать их командам, которые их не поддерживают.источник
unset IFS
в первом примере?IFS=$'\n'
но это работает не во всех оболочках. Или,IFS='<a-litteral-newline-here>'
но это не очень разборчиво. Или мы можем вместо этого разделить слова (пробел, табуляция, новая строка), как вы получаете со значением по умолчанию $ IFS, или если вы сбросили IFS и также работаете здесь.IFS
, потому что мы знаем, что вseq
выводе нет пробелов, которые мы должны избежать, чтобы не разбиваться. В основном это делается для того, чтобы убедиться, что вы понимаете, отIFS
чего зависит этот пример , что может иметь значение для другой команды генерации списка.Используйте «seq» - выведите последовательность чисел
ПОСЛЕДНЯЯ ПЕРВАЯ ВКЛЮЧЕНИЕ
источник
Как предлагали другие, вы можете использовать bc:
источник