Adicionar 1 a uma variável não funciona conforme o esperado (aritmética do Bash)

16

Se eu escrever o seguinte em um terminal bash:

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

Eu recebo 11, não 13 como eu esperava !!!!!

Pesquisei no Google e não consigo explicar nada ou descobrir como posso aumentar o número. (Na verdade, eu quero terminar com B = "0013" e incrementar um a cada vez, pois estou usando isso como prefixo dos meus backups)

Robert3452
fonte
2
Cuidado com os zeros à esquerda em praticamente qualquer idioma originário do UNIX. Isso normalmente significa octal.
Joshua
Não, você não é, você recebe 1011 binário
Ken Mollerup 28/09

Respostas:

28

Isso ocorre porque os números que começam com 0são tratados como Octal por bash, portanto, estão fazendo adição Octal (Base 8). Para obter adição decimal para essa estrutura, você precisa definir explicitamente a Base ou não usá-la 00completamente.

Para decimal, a base é 10, denotada por 10#:

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

Você pode tentar este comando para obter a resposta:

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

Mais informações sobre o bccomando podem ser encontradas aqui .

bc página de manual:

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.
bisbilhoteiro
fonte
4
Em vez de usar echoum canal, você pode usar a sintaxe "here string" do Bash. O efeito é o mesmo, mas IMHO a "string aqui" é mais bonita: bc <<< "$A + 1":-)
Byte Commander
Uma introdução de uma ou duas frases do bccomando, além de um herelink, seria útil.
WinEunuuchs2Unix 11/11/16
2

Um método alternativo pode ser manter suas variáveis ​​como números inteiros e convertê-las em uma sequência no final:

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

Esse estilo de trabalhar com números inteiros em matemática e converter em string para a resposta é mais intuitivo para mim, pois estou acostumado à programação BASIC. Aprecio que o Bash não tem digitação variável como C e BASIC, mas fingir que me faz feliz.

WinEunuuchs2Unix
fonte
Este foi um teste para destacar o problema que eu estava tendo. Eu li a variável inicial pegando a saída de outro comando que é texto e tem zeros à esquerda.
precisa saber é o seguinte
Ah ... a história sempre explica como chegamos ao presente.
WinEunuuchs2Unix 11/11/16
@ Robert3452 Você também pode eliminar os zeros à esquerda:A="0012"; A=$((10#$A))
wjandrea 17/16