
Como duas datas podem ser comparadas em um shell?
Aqui está um exemplo de como eu gostaria de usar isso, embora não funcione como está:
todate=2013-07-18
cond=2013-07-15
if [ $todate -ge $cond ];
then
break
fi
Como posso alcançar o resultado desejado?
Responder1
A resposta certa ainda está faltando:
todate=$(date -d 2013-07-18 +%s)
cond=$(date -d 2014-08-19 +%s)
if [ $todate -ge $cond ];
then
break
fi
Observe que isso requer data GNU. A sintaxe equivalente date
para BSD date
(como encontrada no OSX por padrão) édate -j -f "%F" 2014-08-19 +"%s"
Responder2
Pode usar uma comparação de strings no estilo ksh para comparar a ordem cronológica [de strings em formato de ano, mês, dia].
date_a=2013-07-18
date_b=2013-07-15
if [[ "$date_a" > "$date_b" ]] ;
then
echo "break"
fi
Felizmente, quando [strings que usam o formato AAAA-MM-DD] são classificadas* em ordem alfabética, elas também são classificadas* em ordem cronológica.
(* - classificado ou comparado)
Nada sofisticado é necessário neste caso. yay!
Responder3
Está faltando o formato de data para a comparação:
#!/bin/bash
todate=$(date -d 2013-07-18 +"%Y%m%d") # = 20130718
cond=$(date -d 2013-07-15 +"%Y%m%d") # = 20130715
if [ $todate -ge $cond ]; #put the loop where you need it
then
echo 'yes';
fi
Você também está sentindo falta de estruturas de loop. Como planeja conseguir mais datas?
Responder4
O operador -ge
só funciona com números inteiros, o que não acontece com suas datas.
Se o seu script for um script bash ou ksh ou zsh, você poderá usar o <
operador. Este operador não está disponível no dash ou em outros shells que não vão muito além do padrão POSIX.
if [[ $cond < $todate ]]; then break; fi
Em qualquer shell, você pode converter as strings em números respeitando a ordem das datas simplesmente removendo os travessões.
if [ "$(echo "$todate" | tr -d -)" -ge "$(echo "$cond" | tr -d -)" ]; then break; fi
Alternativamente, você pode usar o tradicional e usar o expr
utilitário.
if expr "$todate" ">=" "$cond" > /dev/null; then break; fi
Como a invocação de subprocessos em um loop pode ser lenta, você pode preferir fazer a transformação usando construções de processamento de string de shell.
todate_num=${todate%%-*}${todate#*-}; todate_num=${todate_num%%-*}${todate_num#*-}
cond_num=${cond%%-*}${cond#*-}; cond_num=${cond_num%%-*}${cond_num#*-}
if [ "$todate_num" -ge "$cond_num" ]; then break; fi
Obviamente, se você puder recuperar as datas sem os hífens, poderá compará-las com -ge
.