Додавання 1 до змінної не працює як очікувалося (арифметика Баша)


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 сторінка 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.

4
Замість використання echoі труби ви можете використовувати синтаксис "тут рядок" Баша. Ефект той самий, але IMHO "тут рядок" прекрасніше: bc <<< "$A + 1":-)
Байт командир

Введення bcкоманди з одним або двома пропозиціями на додаток до hereпосилання було б корисним.
WinEunuuchs2Unix

2

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

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

Цей стиль роботи з цілими числами з математики та перетворення на рядок для відповіді для мене більш інтуїтивно зрозумілий, оскільки я звик до програмування BASIC. Я вдячний, що Bash не має змінних типів типу C та BASIC, але робити вигляд, що це робить мене робить щасливим.


Це було тестом, щоб висвітлити проблему, яку я мав. Я читаю початкову змінну, беручи висновок іншої команди, яка є текстом і має провідні нулі.
Robert3452

Ах ... історія завжди пояснює, як ми дійшли до сьогодення.
WinEunuuchs2Unix

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