Comment comparer deux dates dans un shell?
Voici un exemple de la façon dont j'aimerais utiliser ceci, bien que cela ne fonctionne pas tel quel:
todate=2013-07-18
cond=2013-07-15
if [ $todate -ge $cond ];
then
break
fi
Comment puis-je atteindre le résultat souhaité?
shell-script
shell
date
Abdul
la source
la source
Réponses:
La bonne réponse est toujours manquante:
Notez que cela nécessite une date GNU. La
date
syntaxe équivalente pour BSDdate
(comme dans OSX par défaut) est la suivante:date -j -f "%F" 2014-08-19 +"%s"
la source
timeout=$(`date +%Y%m%d%H%M%S` + 500)
) est évidemment fausse.date -d 2013-07-18 +%s%N
Il vous manque le format de date pour la comparaison:
Il vous manque également des structures en boucle. Comment comptez-vous obtenir plus de dates?
la source
date
MacOS fourni.date -d
est non standard et ne fonctionne pas sous UNIX typique. Sur BSD, il tente même de définir la valeur kenelDST
.Peut utiliser une comparaison de chaînes standard pour comparer l'ordre chronologique [des chaînes dans un format année, mois et jour].
Heureusement, lorsque [les chaînes qui utilisent le format AAAA-MM-JJ] sont triées * par ordre alphabétique, elles sont également triées * par ordre chronologique.
(* - trié ou comparé)
Rien d'extraordinaire n'est nécessaire dans ce cas. Yay!
la source
if [ $(sed -e s/-//g <<< $todate) -ge $(sed -e s/-//g <<< $cond) ];
… Ce format de date a été conçu pour être trié à l’aide du tri alphanumérique standard, ou pour-
être épuré et trié numériquement.Ce n'est pas un problème de structures en boucle mais de types de données.
Ces dates (
todate
etcond
) sont des chaînes, pas des nombres, vous ne pouvez donc pas utiliser l'opérateur "-ge" detest
. (Rappelez-vous que la notation entre crochets est équivalente à la commandetest
.)Ce que vous pouvez faire est d’utiliser une notation différente pour vos dates afin qu’elles soient des entiers. Par exemple:
produira un nombre entier comme 20130715 pour le 15 juillet 2013. Vous pourrez ensuite comparer vos dates avec les opérateurs "-ge" et équivalents.
Mise à jour: si vos dates sont indiquées (par exemple, si vous les lisez à partir d'un fichier au format 2013-07-13), vous pouvez les prétraiter facilement avec tr.
la source
L'opérateur
-ge
ne fonctionne qu'avec des entiers, ce que vos dates ne sont pas.Si votre script est un script bash, ksh ou zsh, vous pouvez utiliser l'
<
opérateur à la place. Cet opérateur n'est pas disponible dans les tirets ni dans d'autres shells ne dépassant pas la norme POSIX.Dans n'importe quel shell, vous pouvez convertir les chaînes en nombres tout en respectant l'ordre des dates en supprimant simplement les tirets.
Alternativement, vous pouvez aller traditionnel et utiliser l'
expr
utilitaire.Comme l’appel de sous-processus dans une boucle peut être lent, vous préférerez peut-être effectuer la transformation à l’aide de structures de traitement de chaîne de commande.
Bien sûr, si vous pouvez récupérer les dates sans les traits d'union, vous pourrez les comparer
-ge
.la source
Je convertis les chaînes en horodatages Unix (secondes depuis le 1.1.1970 0: 0: 0). Ceux-ci peuvent comparer facilement
la source
date
celui fourni avec macOS.Il existe également cette méthode dans l'article intitulé: Calcul simple de la date et de l'heure dans BASH de unix.com.
Ces fonctions sont un extrait d'un script de ce fil!
Usage
la source
date
celui fourni avec macOS.date
àgdate
.réponse spécifique bash
Comme j'aime bien réduire les fourches et permettre bash beaucoup de trucs, voici mon but:
Bien maintenant:
Cela va repeupler les deux variables
$todate
et$cond
, en utilisant un seul fork, avec une sortiedate -f -
qui prend stdio pour lire une date par ligne.Enfin, vous pourriez casser votre boucle avec
Ou en fonction :
Utiliser le script intégré de bash
printf
qui pourrait rendre la date et l'heure en secondes (voirman bash
;-)Ce script utilise un seul fork.
Alternative avec fourchettes limitées et fonction de lecture de date
Cela créera un sous-processus dédié (un seul fork):
Comme l'entrée et la sortie sont ouvertes, l'entrée fifo peut être supprimée.
La fonction:
Note Afin d'éviter des fourches inutiles comme
todate=$(myDate 2013-07-18)
, la variable doit être définie par la fonction elle-même. Et pour permettre la syntaxe libre (avec ou sans guillemets à la chaîne de données), le nom de la variable doit être le dernier argument.Puis date de comparaison:
peut rendre:
si en dehors d'une boucle.
Ou utilisez la fonction bash shell-connector:
ou
(Ce qui n'est pas exactement pareil:
.sh
contient le script de test complet s'il n'a pas été acheté)la source
date -f -
pourrait réduire les besoins en ressources.les dates sont des chaînes, pas des entiers; vous ne pouvez pas les comparer avec des opérateurs arithmétiques standard.
Une approche que vous pouvez utiliser si le séparateur est garanti
-
:Cela fonctionne aussi loin que
bash 2.05b.0(1)-release
.la source
Vous pouvez également utiliser la fonction intégrée de mysql pour comparer les dates. Cela donne le résultat en 'jours'.
Insérez simplement les valeurs
$DBUSER
et$DBPASSWORD
variables en fonction de la vôtre.la source
FWIW: sur Mac, il semble que l'insertion d'une date telle que "2017-05-05" dans la date sera ajoutée à la date et l'heure actuelle, et vous obtiendrez une valeur différente chaque fois que vous la convertirez en heure de début. pour obtenir une heure d'époque plus cohérente pour des dates fixes, incluez des valeurs factices pour les heures, les minutes et les secondes:
Cela peut être une bizarrerie limitée à la version de date fournie avec macOS .... testée sur macOS 10.12.6.
la source
Répondant à @Gilles ("L'opérateur -ge ne fonctionne qu'avec des entiers"), voici un exemple.
datetime
conversions entières versepoch
, la réponse de @ mike-q à l' adresse https://stackoverflow.com/questions/10990949/convert-date-time-string-stro--poch-in-bash :"$curr_date"
est supérieur à (plus récent que)"$old_date"
, mais cette expression est évaluée de manière incorrecte comme suitFalse
:... montré explicitement, ici:
Comparaisons entières:
la source
La raison pour laquelle cette comparaison ne fonctionne pas bien avec une chaîne de date comportant un trait d'union est que le shell suppose qu'un nombre précédé de 0 est un nombre octal, dans ce cas le mois "07". Diverses solutions ont été proposées, mais la plus rapide et la plus simple consiste à supprimer les traits d'union. Bash a une fonctionnalité de substitution de chaîne qui rend cela rapide et facile, alors la comparaison peut être effectuée comme une expression arithmétique:
la source