/ bin / dash: verifique se $ 1 é um número

14

Qual seria a melhor maneira de verificar se $ 1 é um inteiro em / bin / dash?

No bash, eu pude fazer:

[[ $1 =~ ^([0-9]+)$ ]]

Mas isso não parece ser compatível com POSIX e o traço não suporta isso

    
por Martin Vegter 23.04.2015 / 22:59

7 respostas

11

Os seguintes números inteiros detectados, positivos ou negativos, e funcionam sob dash e são POSIX:

Opção 1

echo "$1" | grep -Eq '^[+-]?[0-9]+$' && echo "It's an integer"

Opção 2

case "${1#[+-]}" in
    ''|*[!0-9]*)
        echo "Not an integer" ;;
    *)
        echo "Integer" ;;
esac

Ou, com um pouco de uso do comando : (nop):

! case ${1#[+-]} in *[!0-9]*) :;; ?*) ! :;; esac && echo Integer
    
por 23.04.2015 / 23:11
5

Se dash , bash , ksh , zsh , POSIX sh ou posh ( "uma reimplementao da shell Bourne" sh ); a construção case é a mais amplamente disponível e confiável:

case $1 in (*[!0-9]*|"") false ;; (*) true ;; esac
    
por 23.04.2015 / 23:43
1

Você pode usar o teste -eq na string, com ele mesmo:

$ dash -c 'a="a"; if [ "$a" -eq "$a" ] ; then echo number; else echo not a number; fi' 
dash: 1: [: Illegal number: a
not a number
$ dash -c 'a="0xa"; if [ "$a" -eq "$a" ] ; then echo number; else echo not a number; fi'
dash: 1: [: Illegal number: 0xa
not a number
$ dash -c 'a="-1"; if [ "$a" -eq "$a" ] ; then echo number; else echo not a number; fi'
number

Se a mensagem de erro for um problema, redirecione a saída de erro para /dev/null :

$ dash -c 'a="0xa"; [ "$a" -eq "$a" ] 2>/dev/null|| echo no'
no
    
por 24.04.2015 / 00:00
0

Tente usá-lo como uma expansão aritmética e veja se funciona. Na verdade, você precisa ser um pouco mais rigoroso do que isso, porque as expansões aritméticas ignorariam os espaços iniciais e finais, por exemplo. Portanto, faça uma expansão aritmética e certifique-se de que o resultado expandido corresponda exatamente à variável original.

check_if_number()
{
    if [ "$1" = "$((${1}))" ] 2>/dev/null; then
        echo "Number!"
    else
        echo "not a number"
    fi
}

Isso também aceitaria números negativos - se você realmente quiser excluí-los, adicione uma verificação extra para $((${1} >= 0)) .

    
por 23.04.2015 / 23:15
0

Talvez com expr ?

if expr match "$1" '^\([0-9]\+\)$' > /dev/null; then
  echo "integer"
else 
  echo "non-integer"
fi
    
por 23.04.2015 / 23:28
0

No sistema POSIX, você pode usar expr :

$ a=a
$ expr "$a" - 0 >/dev/null 2>&1
$ [ "$?" -lt 2 ] && echo Integer || echo Not Integer
    
por 24.04.2015 / 10:40
0

Aqui está uma função simples usando o mesmo método da resposta muru :

IsInteger()      # usage: IsInteger string
{               #  returns: flag
        [ "$1" -eq "$1" ] 2> /dev/null
}

Exemplo:

p= n=2a3; IsInteger $n || p="n't" ; printf "'%s' is%s an integer\n" "$n" "$p"
p= n=23;  IsInteger $n || p="n't" ; printf "'%s' is%s an integer\n" "$n" "$p"

Saída:

'2a3' isn't an integer
'23' is an integer
    
por 22.06.2018 / 22:47