日付引数が正しい形式(YYYY-MM-DD)であるかどうかを確認する方法はありますか?
私はこれをウェブから入手しましたが、私にとってはうまくいきません:
date "+%Y-%m-%d" -d "2015-10-11" > /dev/null 2>&1
echo $?
0
の結果を期待していますが、そうではありません。誰かが別の方法を言うことができますか?
これは、bash
の正しい形式(YYYY-MM-DD)をチェックします(組み込みの正規表現一致で)。
_if [[ $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
then echo "Date $1 is in valid format (YYYY-MM-DD)"
else echo "Date $1 is in an invalid format (not YYYY-MM-DD)"
fi
_
実行:
_./script.sh 2015-12-10
_
出力:
Date 2015-12-10 is in valid format (YYYY-MM-DD)
formatのみが日付自体が有効かどうかをチェックしません(質問に記載されているように、「日付引数が正しい形式(YYYY-MM-DD)かどうかをチェックします」)
日付の形式とを確認して日付の値を検証する必要がある場合は、次のようにします。
_if [[ $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && date -d "$1" >/dev/null
then echo "Date $1 is valid and matches the format (YYYY-MM-DD)"
fi
_
これにより、正規表現マッチングに合格した0000-88-77のような無効な日付が破棄されます。
(クレジットはこの提案のために@glenn jackmanに送られます。)
日付が正しい形式であることを検証するための正規表現の書き方を学ぶ必要があります。 yyyy-mm-dd
簡単な方法は、これを1行で行うことです。これにより、日付と正規表現をいじって、すばやく学習できます。
echo
を使用して日付を生成し、次にegrep
を使用して正規表現を適用し、一致が見つかったかどうかを示します。 egrep
のマニュアルページを見てください。-c
オプション。一致の数を出力します。送信するのは1つの日付だけなので、一致が見つかったかどうかによって、カウントは0または1になります。
これがあなたと遊ぶためのあなたのワンライナーです。
echo 0000-00-00 |egrep -c -e 'regular-expression-in-here'
正規表現を挿入して( A.P で始めることができます)、それがどのように機能するかを確認します。日付を変更し、検証する内容を確認します。ここに別のものがありますが、少し異なります。
[0-9]{4}-[0-1][0-9]-[0-3][0-9]
日付のdate
出力が元の値と一致するかどうかを単純に比較できます。
d="2015-10-11"
if [ "`date '+%Y-%m-%d' -d $d 2>/dev/null`" = "$d" ]
then
echo $d is a valid YYYY-MM-DD date
else
echo $d is NOT a valid YYYY-MM-DD date
fi
OSにタグを付けていませんが、ksh
を使用しているため、おそらくLinuxを使用していないと思いますが、mightSolarisを使用している。指定したdate
コマンドは機能しますが、GNU date
用です。ここで、-d
(または--date
)はGNU拡張です。
したがって、単純なオプションはGNU date
を使用することです。GNU coreutilsパッケージをインストールする必要があるか、すでにインストールされている(Solarisでは/usr/sfw/bin
で確認)ことができます。おそらくgdate
またはgnudate
として利用できます。これは、YYYY-MM-DD形式で日付を適切に検証します(2015-31-01を受け入れる他の正規表現の例とは異なります)
代わりに、touch
コマンドを同様の方法で使用できます 移植性が高い(POSIX) 方法
touch -c -d 2015-12-12T00:00:00 /tmp/does-not-exist
-c
を使用して、ファイルが作成されないようにする(ただし、Solarisを使用している場合、一部のバージョンに-d
が不足しているだけでなく、少なくとも一部のバージョンにバグ/機能の誤りがあり、検証されないためにスマートにしようとするため、「2015-02-29」は「 2015-03-01」というエラーは発生しないため、これらのバージョンを日付検証に使用することはできません。)
私はこの方法を好みます。gawk
(または代わりにmawk
がありますが、従来のnawk
にはこれらの時間関数がありません)を前提として、堅牢で移植性があります。
#!/usr/local/bin/gawk -f
BEGIN{
split(ARGV[1],bb,/-/)
tm=mktime( bb[1] " " bb[2] " " bb[3] " 00 00 00")
tms=sprintf("%04i-%02i-%02i",bb[1],bb[2],bb[3])
if (tms==strftime("%Y-%m-%d",tm)) exit 0
exit 1
}
上記
mktime()
は、示されたYYYY-MM-DDのエポックタイムスタンプを決定しますsprintf()
は、YYYY-MM-DD(先頭の0)を正規化しますstrftime()
エポック時間をYYYY-MM-DDに変換し、文字列として比較します追加の変換と比較の理由は、Linuxのglibcの場合(Solaris touch
と同じ問題)のように、疑わしい日付がCライブラリmktime()
によって再解釈されるケースをキャッチするためです。上記)。
YYYY-MM-DDの正しい形式に注意することは、日付の有効性に注意することを意味する場合とそうでない場合があります(何かdate
はdo)、そして YYYY-DD-MM形式の日付 を削除できることを意味する場合さえあります。形式が「日付のような」であることのみを確認したい場合は、正規表現で十分です。
grep -qE "^[0-9]{4}-[01]?[0-9]-[0123]?[0-9]$"
grep -qE "^[12][0-9]{3}-(0?[1-9]|10|11|12)-(0?[1-9]|[12][0-9]|3[01])$"
(Solarisでは、デフォルトのgrep
ではなく/usr/xpg4/bin/grep
を使用してください)最初のものはほとんどの偽の日付を拒否し、2番目のものはほとんどすべての偽の日付を拒否します。 -q
を使用すると、出力はなくなり、期待どおりに戻りコードを使用できます。 (^...$
)を固定するか、正規表現を制限して、有効な部分文字列に単純に一致しないように注意してください。 2015-12-12345