web-dev-qa-db-fra.com

Valider le format de date dans un script shell

Je dois créer un script shell dans lequel l’un des paramètres sera la date au format jj/mm/aaaa. Ma question est, comment puis-je vérifier si la date passée comme paramètre suit vraiment ce format de date? J'ai essayé d'utiliser la commande grep comme ci-dessous:

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

mais il n'a pas donné le bon format car le jour par exemple peut être 33, 34, (...), ce n'est pas vraiment le bon format Quelqu'un sait quelque chose qui peut vraiment vérifier si la date passée suit vraiment le format jj/mm/aaaa? 

9
Jairo Franchi

Utilisez date

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

Si vous n'obtenez pas 0, la date est au format invalide.

20
P̲̳x͓L̳

La solution la plus simple, qui fonctionne toujours parfaitement, est la suivante:

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

Il consiste à combiner 2 chèques:

  • la première partie vérifie que $1 est de ce format: NNNN-NN-NN
  • la deuxième partie vérifie qu'il s'agit d'une date valide

Vous avez besoin des deux chèques parce que:

  • si vous ne faites pas la première vérification, date se termine avec le code 0 même si votre variable est une date valide dans un autre format
  • si vous ne faites pas la deuxième vérification, vous pouvez vous retrouver avec un 0 même pour des variables telles que 2016-13-45
10
Vic Seedoubleyew

Commencez par vérifier le formulaire de saisie à l’aide de la regex. Utilisez ensuite awk pour passer à mm/jj/aaaa et utilisez date pour valider. Vous pouvez utiliser l'expression suivante dans votre instruction 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
augurar
#! /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'`
2
chelabim

Le moyen le plus simple pour dd/mm/yyyy exactement dans Bash est:

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

Ou

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

Que diriez-vous d'utiliser awk:

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

Il affiche "bon" si sa date de validité est indiquée par "mauvais"

2
VDR

`X =" 2016-04-21 "puis vérifiez si la valeur ci-dessous est 1 ou 0.

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

Si la valeur est 1, elle est valide, sinon ce n'est pas valide.

1
Manikandan

Cette fonction attend 2 chaînes, une chaîne de format, une chaîne de date

La chaîne de format utilise les codes de la commande date mais n'inclut pas le '+'

La fonction retourne 0 si la date fournie correspond au format donné, sinon elle retourne 1

datecheck() {
    local format="$1" d="$2"
    [[ "$(date "+$format" -d "$d" 2>/dev/null)" == "$d" ]]
}
1
Karl Kowallis

Voici une fonction permettant de valider certaines données:

# 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
javaPlease42

J'ai écrit ce script bash pour valider la date. Je peux accepter le mont alphanumérique.

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