test com expansão aritmética (primeiro zero)

0

O código ksh88 a seguir leva valores para o mês [m] e ano [y] e calcula o mês anterior [p_m] e o ano do mês anterior [p_m_y].

m é originalmente derivado do comando date e, portanto, tem um zero à esquerda se o mês atual < 10.

m=02
y=2017

if [ $((m-1)) -gt 1 ]
then
    p_m=$((m-1))
    p_m_y=$((y))
else
    p_m=12
    p_m_y=$((y-1))
fi

Neste exemplo p_m está sendo definido como 12, e p_m_y é 2016, então a instrução if parece estar falhando e sempre acionando o código 'else' .... mesmo onde m é maior que 1. Acho que o zero inicial pode ser o problema? A mesma coisa acontece se eu usar [[..]].

Se eu alterar para o abaixo, funciona

if [[ $((m-1)) != 01 ]]

Presumivelmente, isso agora é uma comparação de string, a comparação aritmética não está funcionando. Não é um problema enorme, eu ainda poderia trabalhar com isso.

Mas deve haver uma maneira de fazê-lo funcionar usando a aritmética adequada. Se eu tentar forçar a expansão base10, isso não terá nenhum efeito.

if [[ $((10#$m-1)) -gt 1 ]]
    
por Ben Hamilton 09.05.2017 / 17:11

3 respostas

0

O problema no exemplo específico que você mostra não é que m tenha um zero à esquerda - mesmo que tenha sido tratado como octal, 02 ainda é apenas 2 . O teste que você está usando é:

[ $((m-1)) -gt 1 ]

Mas m-1 > 1 é equivalente a m > 2 . Como 2 não é maior que 2 , a cláusula else será executada. Você pode alterar o teste para simplesmente

[ $m -gt 1 ]

Mas seria muito mais simples usar diretamente os recursos aritméticos do shell:

m=02
y=2017
p_m=$(( (m+10)%12 + 1 ))
p_m_y=$(( y - (m==1) ))

Esse último bit provavelmente merece alguma explicação:

Para p_m , usamos aritmética modular. (m + 10)%12 é equivalente a "dois meses antes (ou dez meses depois), exceto que dezembro é listado como 0". Em seguida, adicionamos um para alcançar "o mês anterior, no intervalo de 1 a 12".

A última linha é mais simples. (m==1) é 1 se m for numericamente igual a 1, senão 0 . Portanto, p_m_y é definido para o ano atual se m não for 1, senão no ano anterior.

Como um aparte, você diz:

m is originally derived from the date command and so has a leading zero if current month < 10.

Este não é necessariamente o caso. No meu sistema:

$ date
2017年  5月  9日 火曜日 13:58:53 EDT
$ LC_ALL=en_US.UTF-8 date
Tue May  9 13:58:53 EDT 2017
$ date '+%Y %m %d' | sed 's/ 0*/ /g'
2017 5 9

Então, se você está preocupado com números sendo interpretados como octal, você pode querer tentar este último.

    
por 09.05.2017 / 19:06
1

Usamos a calculadora dc , na qual o macro a é chamado quando o mês é janeiro = > mês anterior = > 12 e ano é diminuído. Othwerise, nós apenas diminuímos o ano.

m=01
y=2011

set X 'echo "[sa 1- 12]sa $y $m d1- r1- r0 =af" | dc'; shift

p_m=$1  p_m_y=$2

echo "Current month:$m   Current year: $y"
echo "   Prev month:$p_m Prev month year: $p_m_y"
    
por 09.05.2017 / 19:11
0

Isso deve funcionar, mas eu testei em ksh :

if [[ $((m-1)) -eq 1 ]]; then echo "Equal"; fi

Funciona com -gt também.

    
por 09.05.2017 / 17:17

Tags