Добавление 1 к переменной не работает должным образом (арифметика Bash)


16

Если я напишу следующее в терминале Bash:

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

Я получаю 11, а не 13, как я ожидал !!!!!

Я гуглил и не могу ничего объяснить, или понять, как мне увеличить число. (На самом деле я хочу получить B = "0013" и увеличивать единицу каждый раз, когда я использую это в качестве префикса для моих резервных копий)


2
Остерегайтесь лидирующих нулей практически на любом языке, происходящем из UNIX. Это обычно означает восьмеричное.
Джошуа

Нет, ты не получаешь 1011 двоичный файл
Кен Моллеруп,

Ответы:


28

Это связано с тем, что числа, начинающиеся с, 0считаются октальными bash, следовательно, происходит добавление октальных (базовых 8). Чтобы получить десятичное дополнение для этой структуры, вам нужно явно определить Основу или не использовать ее 00полностью.

Для десятичного числа основание равно 10, обозначается как 10#:

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

5

Вы можете попробовать эту команду, чтобы получить ответ:

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

Более подробную информацию о bcкоманде можно найти здесь .

bc справочная страница:

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.

4
Вместо использования echoи канала, вы можете использовать синтаксис Bash «здесь строка». Эффект тот же, но ИМХО "здесь строка" красивее: bc <<< "$A + 1":-)
Byte Commander

Было бы полезно введение bcкоманды в одно или два предложения в дополнение к hereссылке.
WinEunuuchs2Unix

2

Альтернативным методом может быть сохранение ваших переменных в виде целых чисел и преобразование их в строку в конце:

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

Этот стиль работы с целыми числами в математике и преобразования в строку для ответа более интуитивен для меня, так как я привык к программированию на Бейсике. Я ценю, что Bash не имеет типизированной переменной, как C и BASIC, но притворство делает меня счастливым.


Это был тест, чтобы выделить проблему, с которой я столкнулся. Я прочитал исходную переменную, взяв вывод другой команды, которая является текстовой и имеет начальные нули.
Robert3452

Ах ... история всегда объясняет, как мы попали в настоящее.
WinEunuuchs2Unix

@ Robert3452 Вы также можете удалить ведущие нули:A="0012"; A=$((10#$A))
wjandrea
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.