シェルで 2 つの日付を比較するにはどうすればよいでしょうか?

シェルで 2 つの日付を比較するにはどうすればよいでしょうか?

シェルで 2 つの日付を比較するにはどうすればよいでしょうか?

このままではうまく動作しませんが、これをどのように使用したいかの例を以下に示します。

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  

dateこれには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

ありがたいことに、[YYYY-MM-DD 形式を使用する文字列] をアルファベット順に並べ替えると、時系列順にも並べ替えられます。

(* - ソートまたは比較)

この場合、特別なことは何も必要ありません。やったー!

答え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 スクリプトの場合は、<代わりに演算子を使用できます。この演算子は、POSIX 標準をあまり超えない dash またはその他のシェルでは使用できません。

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

関連情報