Wie können zwei Daten in einer Shell verglichen werden?
Hier ist ein Beispiel, wie ich das verwenden möchte, obwohl es nicht wie es ist funktioniert:
todate=2013-07-18
cond=2013-07-15
if [ $todate -ge $cond ];
then
break
fi
Wie kann ich das gewünschte Ergebnis erzielen?
shell-script
shell
date
Abdul
quelle
quelle
Antworten:
Die richtige Antwort fehlt noch:
Beachten Sie, dass hierfür das GNU-Datum erforderlich ist. Die äquivalente
date
Syntax für BSDdate
(wie sie standardmäßig in OSX zu finden ist) lautetdate -j -f "%F" 2014-08-19 +"%s"
quelle
timeout=$(`date +%Y%m%d%H%M%S` + 500)
) ist offensichtlich falsch.date -d 2013-07-18 +%s%N
Ihnen fehlt das Datumsformat für den Vergleich:
Ihnen fehlen auch Schleifenstrukturen. Wie planen Sie, mehr Termine zu bekommen?
quelle
date
mit macOS ausgelieferten.date -d
ist kein Standard und funktioniert unter einem typischen UNIX nicht. Unter BSD wird sogar versucht, den Kenel-Wert festzulegenDST
.Kann einen Standard-Zeichenfolgenvergleich verwenden, um die chronologische Reihenfolge [von Zeichenfolgen im Format Jahr, Monat, Tag] zu vergleichen.
Wenn [Zeichenfolgen im Format JJJJ-MM-TT] in alphabetischer Reihenfolge * sortiert werden, werden sie erfreulicherweise auch in chronologischer Reihenfolge * sortiert.
(* - sortiert oder verglichen)
In diesem Fall ist nichts Besonderes erforderlich. Yay!
quelle
if [ $(sed -e s/-//g <<< $todate) -ge $(sed -e s/-//g <<< $cond) ];
... Dieses Datumsformat wurde so entworfen, dass es nach der normalen alphanumerischen Sortierung sortiert oder-
gestrippt und numerisch sortiert werden kann.Dies ist kein Problem von Schleifenstrukturen, sondern von Datentypen.
Diese Daten (
todate
undcond
) sind Zeichenfolgen und keine Zahlen. Sie können daher nicht den Operator "-ge" von verwendentest
. (Denken Sie daran, dass die Schreibweise in eckigen Klammern dem Befehl entsprichttest
.)Sie können für Ihre Daten eine andere Notation verwenden, sodass es sich um Ganzzahlen handelt. Zum Beispiel:
erzeugt eine Ganzzahl wie 20130715 für den 15. Juli 2013. Dann können Sie Ihre Daten mit "-ge" und entsprechenden Operatoren vergleichen.
Update: Wenn Ihre Daten angegeben sind (z. B. Sie sie aus einer Datei im Format 2013-07-13 lesen), können Sie sie mit tr einfach vorverarbeiten.
quelle
Der Operator arbeitet
-ge
nur mit Ganzzahlen, die Ihre Daten nicht enthalten.Wenn es sich bei Ihrem Skript um ein Bash-, Ksh- oder Zsh-Skript handelt, können Sie
<
stattdessen den Operator verwenden. Dieser Operator ist nicht in Dash- oder anderen Shells verfügbar, die den POSIX-Standard nicht wesentlich überschreiten.In jeder Shell können Sie die Zeichenfolgen in Zahlen konvertieren und dabei die Reihenfolge der Datumsangaben einhalten, indem Sie einfach die Bindestriche entfernen.
Alternativ können Sie das
expr
Dienstprogramm auch auf herkömmliche Weise verwenden .Da das Aufrufen von Unterprozessen in einer Schleife langsam sein kann, ziehen Sie möglicherweise die Transformation mithilfe von Shell-String-Verarbeitungskonstrukten vor.
Wenn Sie die Daten zunächst ohne die Bindestriche abrufen können, können Sie sie natürlich mit denen vergleichen
-ge
.quelle
Ich konvertiere die Strings in Unix-Zeitstempel (Sekunden seit 1.1.1970 0: 0: 0). Diese lassen sich leicht vergleichen
quelle
date
, der mit macOS ausgeliefert wird.Es gibt auch diese Methode aus dem Artikel mit dem Titel: Einfache Datums- und Zeitberechnung in BASH von unix.com.
Diese Funktionen sind ein Auszug aus einem Skript in diesem Thread!
Verwendungszweck
quelle
date
, der mit macOS ausgeliefert wird.date
, indem Sie auf änderngdate
.bash spezifische Antwort
Da ich Gabeln und Bash gerne reduziere , erlaube ich viele Tricks, gibt es mein Ziel:
Na dann:
Dadurch werden beide Variablen neu gefüllt
$todate
und$cond
mit nur einem Fork wird das Ergebnis angezeigtdate -f -
, mit dem stdio für das zeilenweise Lesen eines Datums verwendet wird.Schließlich könnten Sie Ihre Schleife mit brechen
Oder als Funktion :
Mit der eingebauten Bash ,
printf
die das Datum und die Uhrzeit in Sekunden von der Epoche rendern kann (sieheman bash
;-)Dieses Skript verwendet nur eine Gabel.
Alternative mit eingeschränkter Gabel- und Datumsleserfunktion
Dadurch wird ein dedizierter Unterprozess erstellt (nur eine Verzweigung):
Da Ein- und Ausgang offen sind, kann der FIFO-Eintrag gelöscht werden.
Die Funktion:
Hinweis Um unnötige Gabeln wie zu vermeiden
todate=$(myDate 2013-07-18)
, muss die Variable von der Funktion selbst gesetzt werden. Um eine freie Syntax (mit oder ohne Anführungszeichen für die Datenfolge) zuzulassen, muss der Variablenname das letzte Argument sein.Dann Datumsvergleich:
kann rendern:
wenn außerhalb einer Schleife.
Oder verwenden Sie die Shell-Connector-Bash-Funktion:
oder
(Was nicht genau dasselbe ist:
.sh
Enthält das vollständige Testskript, wenn keine Quellen angegeben wurden.)quelle
date -f -
den Ressourcenbedarf reduzieren kann.Daten sind Zeichenfolgen, keine ganzen Zahlen. Sie können nicht mit Standardarithmetikoperatoren verglichen werden.
Ein Ansatz, den Sie verwenden können, wenn das Trennzeichen garantiert ist
-
:Das funktioniert schon seit
bash 2.05b.0(1)-release
.quelle
Sie können auch die eingebaute Funktion von mysql verwenden, um die Daten zu vergleichen. Es gibt das Ergebnis in "Tagen".
Fügen Sie einfach die Werte
$DBUSER
und$DBPASSWORD
Variablen nach Ihren Wünschen ein.quelle
FWIW: Auf einem Mac wird beim Einspeisen eines Datums wie "2017-05-05" die aktuelle Uhrzeit an das Datum angehängt und bei jeder Konvertierung in die Epochenzeit ein anderer Wert angezeigt. Um eine konsistentere Epochenzeit für feste Daten zu erhalten, geben Sie Dummy-Werte für Stunden, Minuten und Sekunden an:
Dies kann eine Seltsamkeit sein, die auf die Version des Datums beschränkt ist, die mit macOS ausgeliefert wurde .... getestet unter macOS 10.12.6.
quelle
Echoing @ Gilles Antwort ("Der Operator -ge funktioniert nur mit ganzen Zahlen"), hier ist ein Beispiel.
datetime
Ganzzahlige Konvertierungen nachepoch
der Antwort von @ mike-q unter https://stackoverflow.com/questions/10990949/convert-date-time-string-to-epoch-in-bash :"$curr_date"
ist größer als (neuer als)"$old_date"
, aber dieser Ausdruck wird fälschlicherweise ausgewertet alsFalse
:... hier explizit gezeigt:
Ganzzahlige Vergleiche:
quelle
Der Grund, warum dieser Vergleich mit einer mit Bindestrich versehenen Datumszeichenfolge nicht gut funktioniert, ist die Annahme, dass eine Zahl mit einer führenden 0 ein Oktal ist, in diesem Fall der Monat "07". Es wurden verschiedene Lösungen vorgeschlagen, aber am schnellsten und einfachsten lassen sich die Bindestriche entfernen. Bash verfügt über eine Funktion zum Ersetzen von Zeichenfolgen, die dies schnell und einfach macht. Der Vergleich kann dann als arithmetischer Ausdruck ausgeführt werden:
quelle