Como verificar o argumento “delta” como “+10”

3

Eu quero passar um valor numérico para um script bash, que pode ser um valor inteiro absoluto (0-100) ou um "delta" relativo como "+10" ou "-50".

Como eu analisaria $1 para verificar + ou - e pegar o texto restante como um valor?

    
por Ze'ev 01.01.2018 / 14:51

5 respostas

1

Com base na ideia da @ frams, podemos tornar a resposta mais curta:

sign=${1//[[:digit:]]}
value=${1//[^[:digit:]]}

${1//[[:digit:]]} exclui parte do dígito de ${1}

${1//[^[:digit:]]} exclui parte não dígito de ${1}

ref: Guia avançado de scripts bash por Mendel Cooper

    
por 01.01.2018 / 17:18
4

Você pode usar ${var:offset:length} para extrair parte de uma variável e comparar o resultado disso, conforme necessário. Se você omitir a parte length , o restante da string a partir do deslocamento será obtido.

if [[ ${1:0:1} == "+" ]]; then
    is_negative=false
    is_delta=true
    arg=${1:1}
elif [[ ${1:0:1} == "-" ]]; then
    is_negative=true
    is_delta=true
    arg=${1:1}
else
    is_negative=false
    is_delta=false
    arg=$1
fi
    
por 01.01.2018 / 14:57
2

Existe um truque para fazer isso

sign='echo $1|sed -e 's/[0-9]//g'';
 num='echo $1|sed -e 's/[+-]//g'';
echo $sign;  # gets + - or empty
echo $num;   # gets the number

sed -e 's/[0-9]//g' excluir todos os dígitos, + - permanece

sed -e 's/[+-]//g' delete + -, os dígitos permanecem

funciona para todos os casos, incluindo 0, +0, -0.

    
por 01.01.2018 / 16:20
1

Com escudo posix

unset -v sign value
value="${1#[-+]}"
if [ "$value" -eq "$value" 2> /dev/null ];then
  [ "$1" != "$value" ] && sign="${1%$value}"
  echo "sign = $sign value = $value"
else
  echo "not a number $1"
fi
    
por 01.01.2018 / 19:33
1

Para o Bash, eu usaria a sintaxe ${var:offset:length} como na resposta do patrix , mas com outra abordagem. Você deve calcular seu valor base antes.

Por exemplo (o valor é relativo à hora atual):

[[ "$1" =~ ^[+-]?(0|[1-9][0-9]*)$ ]] || exit 2

base="$(date +"%-H")"

case "${1:0:1}" in
"+")
    value="${1:1}"                                                                                                                 
    value=$((base + value))
    ;;
"-")
    value="${1:1}"                                                                                                                 
    value=$((base - value))
    ;;
*)
    value="$1"
    ;;
esac

((value < 0)) || ((value > 23)) && exit 2

echo "Task planned for ${value}h"
    
por 02.01.2018 / 01:22