回答:
テストコンストラクトを[[ ]]
正規表現の一致演算子とともに使用して=~
、文字列が正規表現パターンに一致するかどうかを確認できます。
あなたの特定のケースでは、あなたは書くことができます:
[[ $date =~ ^[0-9]{8}$ ]] && echo "yes"
またはより正確なテスト:
[[ $date =~ ^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$ ]] && echo "yes"
# |^^^^^^^^ ^^^^^^ ^^^^^^ ^^^^^^ ^^^^^^^^^^ ^^^^^^ |
# | | ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ |
# | | | | |
# | | \ | |
# | --year-- --month-- --day-- |
# | either 01...09 either 01..09 end of line
# start of line or 10,11,12 or 10..29
# or 30, 31
つまり、希望する形式に一致する正規表現をBashで定義できます。この方法でできること:
[[ $date =~ ^regex$ ]] && echo "matched" || echo "did not match"
ここで&&
、テストが成功した||
場合は後のコマンドが実行され、テストが失敗した場合は後のコマンドが実行されます。
これは、bashでのユーザー入力日付形式の検証における Aleks-Daniel Jakimenkoによるソリューションに基づいていることに注意してください。
他のシェルではgrepを使用できます。シェルがPOSIXに準拠している場合は、
(echo "$date" | grep -Eq ^regex$) && echo "matched" || echo "did not match"
で魚 POSIXに準拠していない、あなたが行うことができます
echo "$date" | grep -Eq "^regex\$"; and echo "matched"; or echo "did not match"
grep
、-E
フラグ付きのコマンドよりも簡単に正規表現のbash構文を理解できると思います。
sh
、fish
やその他のあまり装備されていないシェルを使用している場合に最適なオプションのようです。
bashバージョン3では、「=〜」演算子を使用できます。
if [[ "$date" =~ ^[0-9]{8}$ ]]; then
echo "Valid date"
else
echo "Invalid date"
fi
リファレンス:http : //tldp.org/LDP/abs/html/bashver3.html#REGEXMATCHREF
注:Bashバージョン3.2以降、二重括弧[[]]内の一致する演算子での引用は不要になりました。
文字列が正しい日付かどうかをテストする良い方法は、コマンドdateを使用することです:
if date -d "${DATE}" >/dev/null 2>&1
then
# do what you need to do with your date
else
echo "${DATE} incorrect date" >&2
exit 1
fi
コメントから:書式設定を使用できます
if [ "2017-01-14" == $(date -d "2017-01-14" '+%Y-%m-%d') ]
date -d 2017-11-14e
、これを実行すると、2017年11月14日05:00:00 UTC 2017が返されますが、スクリプトが壊れてしまいます。
私はexpr match
代わりに使用します=~
:
expr match "$date" "[0-9]\{8\}" >/dev/null && echo yes
これは、現在受け入れられている使用の回答よりも優れています。これは、空の文字列にも一致する=~
ため=~
です。仮定するbadvar
定義されていない場合、[[ "1234" =~ "$badvar" ]]; echo $?
(誤って)与え0
ながら、expr match "1234" "$badvar" >/dev/null ; echo $?
正しい結果を与えます1
。
を使用>/dev/null
してexpr match
の出力値を非表示にする必要があります。これは、一致した文字数、または一致が見つからなかった場合は0です。その注意出力値が、その異なる終了ステータス。一致が見つかった場合の終了ステータスは0、そうでない場合の終了ステータスは1です。
一般的な構文expr
は次のとおりです。
expr match "$string" "$lead"
または:
expr "$string" : "$lead"
どこ$lead
正規表現です。exit status
(これに名前はありますか?)lead
の先頭スライスと一致する場合、その値はtrue(0)になりますstring
。たとえば、expr match "abcdefghi" "abc"
終了しますがtrue
、expr match "abcdefghi" "bcd"
終了しますfalse
。(これを指摘してくれた@Carlo Woodへのクレジット。
=~
は空の文字列と一致しません。指定した例では、空のパターンに対して文字列を一致しています。構文はstring =~ pattern
で、空のパターンはすべてに一致します。
expr match "abcdefghi" "^" && echo Matched || echo No match
-とexpr match "abcdefghi" "bcd" && echo Matched || echo No match
-の両方が返され"0\nNo match"
ます。マッチング"a.*f"
が戻るところ"6\nMatched"
。したがって、例で '^'を使用することも不要であり、すでに暗示されています。
=~
一致する空の文字列の動作を合理化できるかどうかではありません。これは予期しない動作であり、エラーを引き起こす可能性があるということです。この回答は特に焦げたので書いたものです。
expr
私に同意します。
正規表現の使用が日付の文字シーケンスが正しいかどうかを判断するのに役立つ場合、日付が有効かどうかを判断するために簡単に使用することはできません。次の例は正規表現を渡しますが、すべて無効な日付です:20180231、20190229、20190431
したがって、日付文字列(としましょうdatestr
)が正しい形式かどうかを検証する場合は、それを解析して、文字列を正しい形式に変換するdate
ように依頼date
するのが最善です。両方の文字列が同一である場合、有効な形式と有効な日付があります。
if [[ "$datestr" == $(date -d "$datestr" "+%Y%m%d" 2>/dev/null) ]]; then
echo "Valid date"
else
echo "Invalid date"
fi