Cadeia de caracteres de argumento para inteiro no bash

48

Tentando descobrir como converter um argumento em um inteiro para executar a aritmética e depois imprimi-lo, por exemplo, para addOne.sh :

echo $1 + 1
>>sh addOne.sh 1
prints 1 + 1
    
por user135986 27.09.2015 / 21:43

5 respostas

62

No bash, um não "converte um argumento em um inteiro para realizar aritmética". No bash, as variáveis são tratadas como inteiro ou string dependendo do contexto.

Para realizar a aritmética, você deve chamar o operador de expansão aritmética $((...)) . Por exemplo:

$ a=2
$ echo "$a + 1"
2 + 1
$ echo "$(($a + 1))"
3

ou geralmente preferido:

$ echo "$((a + 1))"
3

Você deve estar ciente de que o bash (ao contrário do ksh93, zsh ou yash) executa somente a aritmética inteiro . Se você tiver números de ponto flutuante (números com decimais), existem outras ferramentas para ajudar. Por exemplo, use bc :

$ b=3.14
$ echo "$(($b + 1))"
bash: 3.14 + 1: syntax error: invalid arithmetic operator (error token is ".14 + 1")
$ echo "$b + 1" | bc -l
4.14

Ou você pode usar um shell com suporte aritmético de ponto flutuante ao invés de bash:

zsh> echo $((3.14 + 1))
4.14
    
por 27.09.2015 / 21:57
9

Em bash , você pode realizar a conversão de qualquer coisa para inteiro usando printf - v :

printf -v int '%d\n' "$1" 2>/dev/null

O número flutuante será convertido em inteiro, enquanto nada parecerá que um número será convertido para 0. A exponenciação será truncada para o número antes de e

Exemplo:

$ printf -v int '%d\n' 123.123 2>/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' 1e10 2>/dev/null
$ printf '%d\n' "$int"
1
    
por 28.09.2015 / 04:16
6

De outra forma, você pode usar expr

Ex:

$ version="0002"
$ expr $version + 0
2
$ expr $version + 1
3
    
por 17.05.2017 / 18:38
3

Uma situação semelhante surgiu recentemente ao desenvolver scripts bash para serem executados em ambientes Linux e OSX. O resultado de um comando no OSX retornou uma string contendo o código do resultado; ou seja, " 0" . Claro, isso não foi testado corretamente no seguinte caso:

if [[ $targetCnt != 0 ]]; then...

A solução foi forçar (ou seja, 'converter') o resultado para um número inteiro, semelhante ao que @ John1024 respondeu acima, para que funcionasse como esperado:

targetCnt=$(($targetCnt + 0))
if [[ $targetCnt != 0 ]]; then...
    
por 04.08.2016 / 15:33
-1

se preocupam com códigos de cores, mesmo em rastreio ( -x ) eles não aparecerão, o que daria é que a cadeia que deveria ser um número é encapsulada, não importa como você imprime.

    
por 01.02.2018 / 21:38

Tags