Agregar 1 a una variable no funciona como se esperaba (aritmética Bash)


16

Si escribo lo siguiente en un terminal bash:

A="0012"
B=$((A+1))
echo $B

¡Obtuve 11, no 13 como esperaba!

He buscado en Google y no puedo explicarlo en absoluto, o averiguar cómo puedo aumentar el número. (De hecho, quiero terminar con B = "0013" e incrementar uno cada vez, ya que estoy usando esto como prefijo para mis copias de seguridad)


2
Tenga cuidado con los ceros a la izquierda en prácticamente cualquier idioma que se origine en UNIX. Esto normalmente significa octal.
Joshua

No, no estás, obtienes 1011 binario
Ken Mollerup

Respuestas:


28

Esto se debe a que los números que comienzan con 0son tratados como Octal bash, por lo tanto, está haciendo la adición de Octal (Base 8). Para obtener una adición decimal para esta estructura, debe definir explícitamente la Base o no usarla por 00completo.

Para Decimal, la Base es 10, denotada por 10#:

$ A="10#0012"
$ echo $((A+1))
13

5

Puede probar este comando para obtener la respuesta:

A="0012"
echo $A + 1 | bc

Más información sobre el bccomando se puede encontrar aquí .

bc página man:

NAME
       bc - An arbitrary precision calculator language

SYNTAX
       bc [ -hlwsqv ] [long-options] [  file ... ]

DESCRIPTION
       bc is a language that supports arbitrary precision numbers with interactive execution of statements.  There are some similarities
       in the syntax to the C programming language.  A standard math library is available by command line  option.   If  requested,  the
       math  library is defined before processing any files.  bc starts by processing code from all the files listed on the command line
       in the order listed.  After all files have been processed, bc reads from the standard input.  All code is executed as it is read.
       (If a file contains a command to halt the processor, bc will never read from the standard input.)

       This  version of bc contains several extensions beyond traditional bc implementations and the POSIX draft standard.  Command line
       options can cause these extensions to print a warning or to be rejected.  This document describes the language accepted  by  this
       processor.  Extensions will be identified as such.

44
En lugar de usar echoy una tubería, puede usar la sintaxis "aquí cadena" de Bash. El efecto es el mismo, pero en mi humilde opinión la "cadena de aquí" es más hermosa: bc <<< "$A + 1":-)
Byte Commander

Sería útil bcuna introducción de una o dos oraciones del comando además de un hereenlace.
WinEunuuchs2Unix

2

Un método alternativo puede ser mantener sus variables como enteros y convertirlas en una cadena al final:

A=12
B=$((A+1))
echo $B
13
C=$( printf '%04d' $B )
echo $C
0013

Este estilo de trabajar con enteros en matemáticas y convertir a cadenas para la respuesta es más intuitivo para mí, ya que estoy acostumbrado a la programación BÁSICA. Aprecio que Bash no tenga una escritura variable como C y BASIC, pero pretender que sí me hace feliz.


Esta fue una prueba para resaltar el problema que estaba teniendo. Leí la variable inicial tomando la salida de otro comando que es texto y tiene ceros a la izquierda.
Robert3452

Ah ... la historia siempre explica cómo llegamos al presente.
WinEunuuchs2Unix

@ Robert3452 También puede despojar ceros a la izquierda:A="0012"; A=$((10#$A))
wjandrea
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.