Как сравнить две даты в оболочке?

Как сравнить две даты в оболочке?

Как можно сравнить две даты в ракушке?

Вот пример того, как я хотел бы это использовать, хотя в чистом виде это не работает:

todate=2013-07-18
cond=2013-07-15

if [ $todate -ge $cond ];
then
    break
fi                           

Как добиться желаемого результата?

решение1

Правильный ответ все еще отсутствует:

todate=$(date -d 2013-07-18 +%s)
cond=$(date -d 2014-08-19 +%s)

if [ $todate -ge $cond ];
then
    break
fi  

Обратите внимание, что для этого требуется дата GNU. Эквивалентный dateсинтаксис для BSD date(по умолчанию в OSX) —date -j -f "%F" 2014-08-19 +"%s"

решение2

Можно использовать сравнение строк в стиле ksh для сравнения хронологического порядка [строк в формате год, месяц, день].

date_a=2013-07-18
date_b=2013-07-15

if [[ "$date_a" > "$date_b" ]] ;
then
    echo "break"
fi

К счастью, когда [строки, использующие формат ГГГГ-ММ-ДД] сортируются* в алфавитном порядке, они также сортируются* в хронологическом порядке.

(* - отсортировано или сравнено)

В этом случае ничего особенного не требуется. Ура!

решение3

Для сравнения не указан формат даты:

#!/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

Вам тоже не хватает цикличных структур, как вы планируете получить больше дат?

решение4

Оператор -geработает только с целыми числами, к которым ваши даты не относятся.

Если ваш скрипт — это скрипт bash, ksh или zsh, вы можете использовать оператор <вместо него. Этот оператор недоступен в dash или других оболочках, которые не выходят далеко за рамки стандарта POSIX.

if [[ $cond < $todate ]]; then break; fi

В любой оболочке вы можете преобразовать строки в числа, соблюдая порядок дат, просто удалив дефисы.

if [ "$(echo "$todate" | tr -d -)" -ge "$(echo "$cond" | tr -d -)" ]; then break; fi

В качестве альтернативы вы можете пойти традиционным путем и воспользоваться exprутилитой.

if expr "$todate" ">=" "$cond" > /dev/null; then break; fi

Поскольку вызов подпроцессов в цикле может быть медленным, вы можете предпочесть выполнить преобразование с использованием конструкций обработки строк оболочки.

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

Конечно, если вы изначально сможете извлечь даты без дефисов, вы сможете сравнить их с -ge.

Связанный контент