instrução de caso não se comportando como esperado (função fuzzytime ())

1
FuzzyTime()
{
local tmp=$( date +%H )

case $((10#$tmp)) in
    [00-05] )
        wtstr="why don't you go to bed"
        ;;
    [06-09] )
        wtstr="I see your very eager to start the day"
        ;;
    [10-12] )
        wtstr="and a very good day too you"
        ;;
    [13-18] )
        wtstr="Good Afternoon"
        ;;
    [19-21] )
        wtstr="Good Evening"
        ;;
    [22-23] )
        wtstr="it is getting late, it's time to party or go to bed"
        ;;
    *)
        wtstr="guess the planet your on has more than a 24 hour rotation"
        echo 'case value is:' $tmp
        ;;
esac
}

A variável case representa horas em um contexto de 24 horas, no entanto, parece que os números 08 e 17 causam um problema. Eu resolvi o 08 usando $((10#$tmp)) mas agora 17 é um problema; algum conselho? Este é o meu primeiro script bash sempre tão triste de antemão se esta é uma pergunta boba.

    
por Peter Atkin 09.05.2016 / 16:55

3 respostas

2

[] indica intervalos de caracteres: [10-12] significa dígitos 1 2 e o intervalo entre dígitos 0-1 - isso corresponderá a um único dígito no intervalo 0-2 .

Use comparações simples com if-elif-else-fi :

if [ "$tmp" -ge 0 ] && [ "$tmp" -le 5 ]; then
  echo "<0,5>"
elif [ "$tmp" -ge 6 ] && [ "$tmp" -le 9 ]; then
  echo "<6,9>"
  #...
else
  #...
fi

(Ou você pode iterar sobre uma matriz de limites de intervalo se quiser cada intervalo, mas também pode codificá-lo nesse caso - como você está tentando fazer).

Editar: versão da matriz solicitada:

FuzzyTime(){
  local needle=$1 #needle is $1
  : ${needle:=$( date +%H )} #if no needle is empty, set it to "$(date +%H)
  local times=( 0 6 10 13 19 22 24 0 ) 
  local strings=( 
          "why don't you go to bed"
          "I see your very eager to start the day"
          "and a very good day too you"
          "Good Afternoon"
          "Good Evening"
          "it is getting late, it's time to party or go to bed"
          "guess the planet your on has more than a 24 hour rotation"
          )
    local b=0
    # length(times) - 2 ==  index of the penultimate element 
    local B="$((${#times[@]}-2))" 
    for((; b<B; b++)); do
      if ((needle >= times[b] && needle < times[b+1])); then break; fi
    done
  echo "${strings[$b]}"
}

FuzzyTime "$1"
teste

:

$ for t in {0..27}; do FuzzyTime "$t"; done
0 -- why don't you go to bed
1 -- why don't you go to bed
2 -- why don't you go to bed
3 -- why don't you go to bed
4 -- why don't you go to bed
5 -- why don't you go to bed
6 -- I see your very eager to start the day
7 -- I see your very eager to start the day
8 -- I see your very eager to start the day
9 -- I see your very eager to start the day
10 -- and a very good day too you
11 -- and a very good day too you
12 -- and a very good day too you
13 -- Good Afternoon
14 -- Good Afternoon
15 -- Good Afternoon
16 -- Good Afternoon
17 -- Good Afternoon
18 -- Good Afternoon
19 -- Good Evening
20 -- Good Evening
21 -- Good Evening
22 -- it is getting late, it's time to party or go to bed
23 -- it is getting late, it's time to party or go to bed
24 -- guess the planet your on has more than a 24 hour rotation
25 -- guess the planet your on has more than a 24 hour rotation
26 -- guess the planet your on has more than a 24 hour rotation
27 -- guess the planet your on has more than a 24 hour rotation
    
por 09.05.2016 / 17:07
0
[root@localhost ~]# FuzzyTime
-bash: ((: 09: value too great for base (error token is "09")
-bash: ((: 09: value too great for base (error token is "09")
-bash: ((: 09: value too great for base (error token is "09")
-bash: ((: 09: value too great for base (error token is "09") 
-bash: ((: 09: value too great for base (error token is "09")
-bash: ((: 09: value too great for base (error token is "09"
guess the planet your on has more than a 24 hour rotation

[root@localhost ~]# FuzzyTime 9
I see your very eager to start the day

a solução temp parece ser:

user=$( whoami ) 
ltime=$( date +%H%M )
new=$(echo $( date +%H ) | sed 's/^0*//')
outputFT=$(FuzzyTime $new)

echo 'Hello '$user 'its' $ltime 'hours,' $outputFT
# echo 'Hello '$user 'its' $ltime 'hours,' $FuzzyTime

Meu problema parece girar em torno de obter uma maneira automatizada de colocar o tempo em um formato de sistema BASH gosta, parece que qualquer número único dígito percorre o erro acima 0-9. (ainda realmente amo a solução array).

    
por 10.05.2016 / 09:07
0

bash / traço / ksh / zsh etc usam a mesma regra de correspondência para case padrões do que para expansão de nome de caminho ou globalização de nome de arquivo, portanto seu shell está interpretando esses padrões como intervalos (e os intervalos nem são válidos) .

case também permite separar vários padrões com | .

Teste 0[0-5]) , 0[6-9]) , 1[0-2]) , etc no seu caso, em vez de corresponder ao padrão.

por exemplo. assim:

case $((10#$tmp)) in
    0[0-5]) wtstr="why don't you go to bed" ;;
    0[6-9]) wtstr="I see you're very eager to start the day" ;;
    1[0-2]) wtstr="and a very good day too you" ;;
    1[3-8]) wtstr="Good Afternoon" ;;
    19|2[01]) wtstr="Good Evening" ;;
    2[23]) wtstr="it is getting late, it's time to party or go to bed" ;;
    *) wtstr="guess the planet your on has more than a 24 hour rotation"
       echo 'case value is:' $tmp
       ;;
esac
    
por 10.05.2016 / 10:34