Intentando descubrir cómo convertir un argumento en un entero para realizar operaciones aritméticas y luego imprimirlo, digamos para addOne.sh
:
echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
Intentando descubrir cómo convertir un argumento en un entero para realizar operaciones aritméticas y luego imprimirlo, digamos para addOne.sh
:
echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
Respuestas:
En bash, uno no "convierte un argumento en un entero para realizar operaciones aritméticas". En bash, las variables se tratan como un entero o una cadena según el contexto.
Para realizar la aritmética, debe invocar el operador de expansión aritmética $((...))
. Por ejemplo:
$ a=2
$ echo "$a + 1"
2 + 1
$ echo "$(($a + 1))"
3
o generalmente preferido:
$ echo "$((a + 1))"
3
Debe tener en cuenta que bash (a diferencia de ksh93, zsh o yash) solo realiza aritmética de enteros . Si tiene números de coma flotante (números con decimales), existen otras herramientas para ayudarlo. Por ejemplo, use bc
:
$ b=3.14
$ echo "$(($b + 1))"
bash: 3.14 + 1: syntax error: invalid arithmetic operator (error token is ".14 + 1")
$ echo "$b + 1" | bc -l
4.14
O puede usar un shell con soporte aritmético de coma flotante en lugar de bash:
zsh> echo $((3.14 + 1))
4.14
En bash
, puede realizar la conversión de cualquier cosa a entero usando printf -v :
printf -v int '%d\n' "$1" 2>/dev/null
El número flotante se convertirá en entero, mientras que cualquier cosa que no parezca un número se convertirá en 0. La exponenciación se truncará en el número anterior e
Ejemplo:
$ printf -v int '%d\n' 123.123 2>/dev/null
$ printf '%d\n' "$int"
123
$ printf -v int '%d\n' abc 2>/dev/null
$ printf '%d\n' "$int"
0
$ printf -v int '%d\n' 1e10 2>/dev/null
$ printf '%d\n' "$int"
1
printf -v
esto se puede lograr con la sustitución de comandos:int="$(printf '%d' 123.123 2>/dev/null)"
bash
usted usó?
Una situación similar surgió recientemente al desarrollar scripts de bash para ejecutarse en entornos Linux y OSX. El resultado de un comando en OSX devolvió una cadena que contiene el código de resultado; es decir, " 0"
. Por supuesto, esto no se pudo probar correctamente en el siguiente caso:
if [[ $targetCnt != 0 ]]; then...
La solución fue forzar (es decir, 'convertir') el resultado a un número entero, similar a lo que @ John1024 respondió anteriormente para que funcione como se esperaba:
targetCnt=$(($targetCnt + 0))
if [[ $targetCnt != 0 ]]; then...
==
etc en [[
(también [
conocido como test
) hacer una comparación de cadenas. Existen diferentes operadores para la comparación aritmética, por ejemplo [[ $targetcnt -ne 0 ]]
; vea la página de manual (o información) en Expresiones condicionales. Para recortar espacios específicamente, puede usar [
una expansión variable sin comillas [ $targetcnt == 0 ]
para obtener una división de palabras predeterminada (NO se hace en [[
), pero en general ese enfoque lo lleva al peligro.
importa los códigos de color, incluso en trace ( -x
) no aparecerán, lo que lo delataría es que la cadena que se supone que es un número está entre comillas, sin importar cómo la imprima.
$((var+var))
fallar incluso aunque si tú echo
o printf
ambos vares son lo mismo. No conozco la solución, ya que solo pude solucionarla deshabilitando los códigos de color en la fuente de la salida. Para detectarlo en los registros de seguimiento, verá la variable asignada como infractor var='0'
mientras que debería ser simplementevar=0
sed
si no puede deshabilitarla
printf "1 + %s\n" $1 won't do ?