2013-09-11 39 views
8

我必須創建一個Shell腳本,其中一個參數將是格式爲dd/mm/yyyy的日期。我的問題是,我怎樣才能檢查作爲參數傳遞的日期是否真的遵循這個日期格式?我試圖用如下grep命令:在shell腳本中驗證日期格式

if echo "$1" | grep -q '^[0-3][0-9]/[0-1][0-9]/[0-9]\{4\}$' 

,但它並沒有給出正確的格式,因爲例如當天可到33,34,(...),這是不是真的正確的格式。任何人都知道可以檢查日期是否真的遵循格式dd/mm/yyyy的內容嗎?

+0

另請參閱http://unix.stackexchange.com/a/236374/106927 –

回答

19

使用date

date "+%d/%m/%Y" -d "09/99/2013" > /dev/null 2>&1 
is_valid=$? 

如果你沒有得到0,則日期的格式無效。

+0

感謝您的回答。這真的有效,但只適用於格式mm/dd/yyyy。如果您在終端上檢查選項-d,請檢查格式mm/dd/yyyy。我試圖改變格式,但不會影響方式,因爲使用了date命令的-d選項。 –

+4

WTF?問題是「怎樣才能檢查Date作爲參數傳遞是否真的遵循這個Date Format''。這不檢查任何東西。 ''日期''接受不同格式的日期。例如「tomorrow」是一個有效的格式,「date -d」明天+ 5個月20:00:01'也是有效的。 –

+0

也'日期-d '05/20/1900'''爲我引發一個錯誤。它還取決於您的體系結構(對於64位系統,日期範圍可能更大)。這絕對不是要走的路。改爲使用[konsolebox的答案](http://stackoverflow.com/a/18736035/2698019)。 –

2

首先,使用正則表達式檢查輸入的形式。然後使用awk切換到mm/dd/yyyy並使用日期進行驗證。您可以使用您的if聲明下面的表達式:

echo "$1" | egrep -q '^[0-3][0-9]/[0-1][0-9]/[0-9]{4}$' && date -d "$(echo "$1" | awk 'BEGIN{FS=OFS="/"}{print $2"/"$1"/"$3}')" >/dev/null 2>&1 
2
dd/mm/yyyy恰好擊

簡單的方法是:

if [[ $1 == [0-3][0-9]/[0-1][0-9]/[0-9][0-9][0-9][0-9] ]] 

或者

if [[ $1 =~ ^[0-3][0-9]/[0-1][0-9]/[0-9]{4}$ ]] 
+0

這正是OP所說的_didn't_ work ,因爲它接受像33/19/2000這樣的無效日期。 – augurar

+0

@augurar是的,我可以做出更準確的日期,但是接受的解決方案甚至可以接受其他格式,而不僅僅是'dd/mm/yyyy'。 – konsolebox

2

如何使用awk

echo "31/12/1999" | awk -F '/' '{ print ($1 <= 31 && $2 <= 12 && match($3, /^[1-9][1-9][1-9][1-9]$/)) ? "good" : "bad" }' 

它打印出 「良好」,其有效日期,否則打印 「壞」

+0

這會驗證日期,例如'31/02/2012'或'29/02/2001'或'31/04/2000'或...':(' –

+0

我有需要在多個文件中驗證多個日期格式,我已經準備好了獲取日期,這個解決方案比KonsoleBox或PxL的要好。有人說,請求中日期的格式與此解決方案不同。它應該是 'echo「31/12/1999」| awk -F'/''{print($ 1 <= 12 && $ 2 <= 31 && match($ 3,/^[1-9] [1-9] [1-9] [1-9] $ /)) ? 「好」:「壞」}'' 唯一需要注意的是即使這不是約會,'02/30/2014'也會通過,但這仍然適合我的需求。 – JNevill

1

這裏有一個功能做一些數據驗證這一點:

# Script expecting a Date parameter in MM-DD-YYYY format as input 
verifyInputDate(){ 
    echo ${date} | grep '^[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]$' 
    if [ $? -eq 0 ]; then 
     echo "Date is valid" 
    else 
      echo "Date is not valid" 
    fi 
} 
+1

這不比OP的例子好。像「99/87/0000」這樣的日期會通過你的grep。 – JNevill

-1

塊引用

DATE = "$*" 

[[ "${DATE}" != @(((([123][0]|[012][1-9])|3[1])?([ \/._-])(0[13578]|1[02])?([ \/._-])(19|20)[0-9][0-9])|(([123][0]|[012][1-9])?([ \/._-])\ 
(0[469]|11)?([ \/._-])(19|20)[0-9][0-9])|(([12][0]|[01][1-9]|2[1-8])?([ \/._-])02?([ \/._-])(19|20)[0-9][0-9])|(29?([ \/._-])02?([ \/._-])\ 
(19|20(0[48]|[2468][048]|[13579][26])))) ]] && echo error || echo good) 
+0

嗨,爲什麼你在'echo good'之後加''''? – chelabim

2
#! /bin/bash 

isDateInvalid() 
{ 
    DATE="${1}" 

    # Autorized separator char ['space', '/', '.', '_', '-'] 
    SEPAR="([ \/._-])?" 

    # Date format day[01..31], month[01,03,05,07,08,10,12], year[1900..2099] 
    DATE_1="((([123][0]|[012][1-9])|3[1])${SEPAR}(0[13578]|1[02])${SEPAR}(19|20)[0-9][0-9])" 

    # Date format day[01..30], month[04,06,09,11], year[1900..2099] 
    DATE_2="(([123][0]|[012][1-9])${SEPAR}(0[469]|11)${SEPAR}(19|20)[0-9][0-9])" 

    # Date format day[01..28], month[02], year[1900..2099] 
    DATE_3="(([12][0]|[01][1-9]|2[1-8])${SEPAR}02${SEPAR}(19|20)[0-9][0-9])" 

    # Date format day[29], month[02], year[1904..2096] 
    DATE_4="(29${SEPAR}02${SEPAR}(19|20(0[48]|[2468][048]|[13579][26])))" 

    # Match the date in the Regex 

    if ! [[ "${DATE}" =~ "^(${DATE_1}|${DATE_2}|${DATE_3}|${DATE_4})$" ]] 
    then 
     echo -e "ERROR - '${DATE}' invalid!" 
    else 
     echo "${DATE} is valid" 
    fi 
} 

echo 
echo "Exp 1: "`isDateInvalid '12/13/3000'` 
echo "Exp 2: "`isDateInvalid '12/11/2014'` 
echo "Exp 3: "`isDateInvalid '12 01 2000'` 
echo "Exp 4: "`isDateInvalid '28-02-2014'` 
echo "Exp 5: "`isDateInvalid '12_02_2002'` 
echo "Exp 6: "`isDateInvalid '12.10.2099'` 
echo "Exp 7: "`isDateInvalid '31/11/2000'` 
1

` X =「2016-04-21」然後檢查下面的值是1還是0.

cal echo $x | cut -c 6-7echo $x | cut -c 1-4 2>/dev/null | grep -c echo $x | cut -c 9-10

如果該值爲1,那麼它是有效的,否則它是無效的。

+0

你的意思是「反引號」?你應該在你的答案中輸入它們,否則它將不起作用,因爲目前它們*是單引號。 –

8

的最簡單的解決方案,即仍然運轉完好,如下:

if [[ $1 =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] && date -d "$1" >/dev/null 2>&1 
    ... 

它包括在組合2個檢查:

  • 第一部分檢查該$1是這種格式:NNNN-NN-NN
  • 第二部分檢查它是否是有效日期

您需要兩次檢查,因爲:

  • ,如果你不這樣做的第一次檢查,date將碼0退出,即使如果您在變量是有效日期另一種格式
  • 唐沒有做第二次檢查,那麼你可以結束爲0甚至變量,如2016-13-45
0

我寫了這個bash腳本來驗證日期。我可以接受mont作爲字母數字。

#!/bin/bash 

function isDateValid { 
    DATE=$1 

    if [[ $DATE =~ ^[0-9]{1,2}-[0-9a-zA-Z]{1,3}-[0-9]{4}$ ]]; then 
     echo "Date $DATE is a number!" 
     day=`echo $DATE | cut -d'-' -f1` 
     month=`echo $DATE | cut -d'-' -f2` 
     year=`echo $DATE | cut -d'-' -f3` 

       if [ "$month" == "01" ] || [ "$month" == "1" ]; then 
         month="Jan" 
       elif [ "$month" == "02" ] || [ "$month" == "2" ]; then 
         month="Feb" 
       elif [ "$month" == "03" ] || [ "$month" == "3" ]; then 
         month="Mar" 
       elif [ "$month" == "04" ] || [ "$month" == "4" ]; then 
         month="Apr" 
       elif [ "$month" == "05" ] || [ "$month" == "5" ]; then 
         month="May" 
       elif [ "$month" == "06" ] || [ "$month" == "6" ]; then 
         month="Jun" 
       elif [ "$month" == "07" ] || [ "$month" == "7" ]; then 
         month="Jul" 
       elif [ "$month" == "08" ] || [ "$month" == "8" ]; then 
         month="Aug" 
       elif [ "$month" == "09" ] || [ "$month" == "9" ]; then 
         month="Sep" 
       elif [ "$month" == "10" ]; then 
         month="Oct" 
       elif [ "$month" == "11" ]; then 
         month="Nov" 
       elif [ "$month" == "12" ]; then 
         month="Dec" 
       fi 

     ymd=$year"-"$month"-"$day 
     echo "ymd: "$ymd 
     dmy=$(echo "$ymd" | awk -F- '{ OFS=FS; print $3,$2,$1 }') 
     echo "dmy: "$dmy 
     if date --date "$dmy" >/dev/null 2>&1; then 
       echo "OK" 
      return 0 
     else 
       echo "NOK" 
      return 1 
     fi 
    else 
     echo "Date $DATE is not a number" 
     return 1 
    fi 
} 


if isDateValid "15-15-2014"; then 
    echo "date is valid =)" 
else 
    echo "bad format date" 
fi 
echo "===================" 
if isDateValid "15-12-2014"; then 
     echo "date is valid =)" 
else 
     echo "bad format date" 
fi 
echo "===================" 
if isDateValid "15-Dec-2014"; then 
     echo "date is valid =)" 
else 
     echo "bad format date" 
fi 
echo "===================" 
if isDateValid "1-May-2014"; then 
     echo "date is valid =)" 
else 
     echo "bad format date" 
fi 
echo "===================" 
if isDateValid "1-1-2014"; then 
     echo "date is valid =)" 
else 
     echo "bad format date" 
fi 
echo "===================" 
if isDateValid "12-12-2014"; then 
     echo "date is valid =)" 
else 
     echo "bad format date" 
fi