Evite bucles en conchas.
Si quieres hacer aritmética, usa awko bc:
awk '
BEGIN{
for (i = 4.00; i < 5.42; i+ = 0.02)
print i
}'
O
bc << EOF
for (i = 4.00; i < 5.42; i += 0.02) i
EOF
Tenga en cuenta que awk(al contrario de bc) funciona con la doublerepresentación de números de coma flotante de sus procesadores (probablemente tipo IEEE 754 ). Como resultado, dado que esos números son aproximaciones binarias de esos números decimales, puede tener algunas sorpresas:
$ gawk 'BEGIN{for (i=0; i<=0.3; i+=0.1) print i}'
0
0.1
0.2
Si agrega un OFMT="%.17g"puede ver el motivo de la falta 0.3:
$ gawk 'BEGIN{OFMT="%.17g"; for (i=0; i<=0.5; i+=0.1) print i}'
0
0.10000000000000001
0.20000000000000001
0.30000000000000004
0.40000000000000002
0.5
bc tiene una precisión arbitraria, por lo que no tiene este tipo de problema.
Tenga en cuenta que, de manera predeterminada (a menos que modifique el formato de salida OFMTo use printfespecificaciones de formato explícito), se awkusa %.6gpara mostrar números de coma flotante, por lo que cambiaría a 1e6 y superior para números de coma flotante superiores a 1,000,000 y truncaría la parte fraccionaria para números altos (100000.02 se mostrará como 100000).
Si realmente necesita usar un bucle cáscara, porque, por ejemplo, desea ejecutar comandos específicos para cada iteración de este bucle, o bien utilizar un depósito de flotación apoyo aritmética de punto como zsh, yasho ksh93o generar la lista de valores con un comando que el anterior (o seqsi está disponible) y repita su salida.
Me gusta:
unset -v IFS # configure split+glob for default word splitting
for i in $(seq 4 0.02 5.42); do
something with "$i"
done
O:
seq 4 0.02 5.42 | while IFS= read i; do
something with "$i"
done
a menos que supere los límites de los números de coma flotante de su procesador, seqmaneja los errores incurridos por aproximaciones de coma flotante con más gracia que la awkversión anterior.
Si no tiene seq(un comando GNU), puede hacer uno más confiable como una función como:
seq() { # args: first increment last
bc << EOF
for (i = $1; i <= $3; i += $2) i
EOF
}
Eso funcionaría mejor para cosas como seq 100000000001 0.000000001 100000000001.000000005. Sin embargo, tenga en cuenta que tener números con una precisión arbitrariamente alta no ayudará mucho si vamos a pasarlos a comandos que no los admiten.