Intento formatear su pregunta, pero de alguna manera sigue sin estar clara. printf "1 + %s\n" $1 won't do ?
Archemar
Respuestas:
89
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:
Usar $ (()) o (()) no es seguro si no sabe cuáles son las cadenas (como la entrada del usuario). Considere esto: foo = foo ((foo + = 0)) Esto bloqueará el script mientras intenta evaluar recursivamente foo. Lo mismo con: foo = foo foo = $ ((foo + 0))
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.1232>/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'1e102>/dev/null
$ printf '%d\n'"$int"1
En otros proyectiles sin printf -vesto se puede lograr con la sustitución de comandos:int="$(printf '%d' 123.123 2>/dev/null)"
Adrian Günter
2
Esto no funciona en bash.
Michael Martinez
@MichaelMartinez ¿estás seguro? ¿Qué versión de bashusted usó?
Cuonglm
GNU bash, versión 4.2.46 (1) -release (x86_64-redhat-linux-gnu)
Michael Martinez
5
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:
==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.
dave_thompson_085
-2
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.
Votado abajo, ya que encuentro su respuesta un poco confusa. ¿Quizás podría agregar a lo que se debe corregir el script?
Time4Tea 01 de
esta fue la respuesta principal en la búsqueda de bash + integer + string, así que agregué una información relacionada que no se incluyó entre las respuestas, es decir, cuando las cadenas están envueltas en códigos de colores, puede que no esté claro por qué operaciones como $((var+var))fallar incluso aunque si tú echoo printfambos 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
untore
Lo que puede hacer es asegurarse de que la salida no tenga códigos de color sedsi no puede deshabilitarla
printf "1 + %s\n" $1 won't do ?
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:o generalmente preferido:
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
:O puede usar un shell con soporte aritmético de coma flotante en lugar de bash:
fuente
De otra manera, puedes usar
expr
Ex:
fuente
En
bash
, puede realizar la conversión de cualquier cosa a entero usando printf -v :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:
fuente
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: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:
fuente
==
etc en[[
(también[
conocido comotest
) 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.fuente
$((var+var))
fallar incluso aunque si túecho
oprintf
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 infractorvar='0'
mientras que debería ser simplementevar=0
sed
si no puede deshabilitarla