it-swarm.com.de

Überprüfen Sie das Datumsformat in einem Shell-Skript

Ich muss ein Shell-Skript erstellen, bei dem einer der Parameter das Datum im Format TT/MM/JJJJ ist. Meine Frage ist, wie kann ich überprüfen, ob das als Parameter übergebene Datum wirklich diesem Datumsformat entspricht? Ich habe versucht, den Befehl grep wie folgt zu verwenden:

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

aber es gab nicht das richtige Format, weil der Tag zum Beispiel 33, 34 (...) sein kann, das ist nicht wirklich das richtige Format. Weiß jemand etwas, das wirklich prüfen kann, ob das Datum wirklich dem Format TT/MM/JJJJ folgt? 

9
Jairo Franchi

Verwenden Sie date

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

Wenn Sie keine 0 erhalten, hat das Datum ein ungültiges Format.

20
P̲̳x͓L̳

Die einfachste Lösung, die noch einwandfrei funktioniert, ist folgende:

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

Es besteht aus der Kombination von 2 Prüfungen:

  • der erste Teil prüft, dass $1 dieses Format hat: NNNN-NN-NN
  • der zweite Teil prüft, ob es ein gültiges Datum ist

Sie benötigen die beiden Prüfungen, weil:

  • wenn Sie die erste Prüfung nicht durchführen, wird date mit dem Code 0 beendet, selbst wenn Ihre Variable ein gültiges Datum in einem anderen Format
  • wenn Sie die zweite Prüfung nicht durchführen, können Sie auch bei Variablen wie 2016-13-45 eine 0 erhalten.
10

Überprüfen Sie zunächst die Form der Eingabe mit dem Regex. Verwenden Sie dann awk, um zu mm/tt/jjjj zu wechseln, und verwenden Sie das Datum zum Bestätigen. Sie können den folgenden Ausdruck in Ihrer if-Anweisung verwenden:

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

Der einfachste Weg für dd/mm/yyyy genau in Bash ist:

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

Oder

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

Wie wäre es mit awk:

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

Es wird "gut" gedruckt, wenn sein gültiges Datum ansonsten "schlecht" ist.

2
VDR

`X =" 2016-04-21 "und dann den Wert unter 1 oder 0 prüfen.

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

Wenn der Wert 1 ist, ist er gültig. Andernfalls ist er ungültig.

1
Manikandan

Diese Funktion erwartet zwei Zeichenfolgen, eine Formatzeichenfolge und eine Datumszeichenfolge

Die Formatzeichenfolge verwendet die Codes des Datumsbefehls, enthält jedoch nicht das '+'.

Die Funktion gibt 0 zurück, wenn das angegebene Datum dem angegebenen Format entspricht. Andernfalls wird 1 zurückgegeben

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

Hier ist eine Funktion, um dies zu überprüfen:

# 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

Ich habe dieses Bash-Skript geschrieben, um das Datum zu bestätigen. Ich kann mont als alphanumerisch akzeptieren.

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

Obwohl die Lösung (wenn [[$ 1 = ~ ^ [0-9] {4} - [0-9] {2} - [0-9] {2} $]] && Datum -d "$ 1">/dev/null 2> & 1) von @ https://stackoverflow.com/users/2873507/vic-seedoubleyew ist am besten für Linux, aber es gibt Fehler, da wir nicht direkt vergleichen können Regex in if-Anweisung. Wir sollten den regulären Ausdruck in eine Variable einfügen und dann diese Variable in der if-Anweisung vergleichen/abgleichen. Darüber hinaus gibt der zweite Teil der if-Bedingung keinen booleschen Wert zurück, sodass dieser Teil ebenfalls einen Fehler verursacht.

Daher habe ich die obige Formel geringfügig geändert, und diese Änderung kann auch für verschiedene andere Formate oder Kombinationen von diesen weiter angepasst werden.

DATEVALUE=2019-11-12
REGEX='^[0-9]{4}-[0-9]{2}-[0-9]{2}$'
if [[ $DATEVALUE =~ $REGEX ]] ; then
    date -d $DATEVALUE 
  if [ $? -eq 0 ] ; then
    echo "RIGHT DATE"
   else 
    echo "WRONG DATE"
  fi
else
 echo "WRONG FORMAT"
fi
0