Les méthodes suivantes rendent inutile d'appeler date
deux fois.
La surcharge d'un appel système peut rendre une commande "simple" 100 fois plus lente que bash faire la même chose dans son propre environnement local.
MISE À JOUR Juste une brève mention de mon commentaire ci-dessus: "100 fois plus lent". Il peut maintenant lire " 500 fois plus lentement" ... Je suis récemment tombé (non, j'ai marché aveuglément) sur ce problème. voici le lien: Un moyen rapide de construire un fichier de test
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
ou
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
if [[ "$M" < "15" ]] ; then M=00
elif [[ "$M" < "30" ]] ; then M=15
elif [[ "$M" < "45" ]] ; then M=30
else M=45
fi
echo $Y.$m.$d $H:$M
Les deux versions ne reviendront que
2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45
Voici la première avec une boucle TEST pour les 60 valeurs {00..59}
for X in {00..59} ; ###### TEST
do ###### TEST
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
M=$X ###### TEST
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
done ###### TEST
printf
oused
et aussi que "inutile"cat
vs <fichier fait une différence réelle d'exécution réelle. lors de la boucle, comme dans mon exemple "500 fois plus lent" .. Il semble donc que l'utilisation du shell autant que possible, et permettre un programme tel quedate
le traitement par lots est ce que je veux dire .. par exemple. Exemple de Gilles-Pad-0 gauche, vs printfVoici un moyen de travailler sur les dates dans le shell. Le premier appel
date
pour obtenir les composants et remplir les paramètres de position ($1
,$2
, etc.) avec les composants (notez que c'est l' un de ces rares cas où vous ne souhaitez utiliser en$(…)
dehors des guillemets doubles, pour briser la chaîne en mots). Effectuez ensuite des calculs, des tests ou tout ce que vous devez faire sur les composants. Assemblez enfin les composants.La partie arithmétique peut être un peu délicate car les coques sont traitées
0
comme un préfixe octal; par exemple ici$(($5/15))
échouerait à 8 ou 9 minutes après l'heure. Puisqu'il y a au plus un leader0
,${5#0}
est sûr pour l'arithmétique. L'ajout de 100 et la suppression ultérieure du1
est un moyen d'obtenir un nombre fixe de chiffres dans la sortie.la source
Peut-être que cela n'a plus d'importance, mais vous pouvez essayer mes propres dateutils . L'arrondi (vers le bas) en minutes est effectué avec
dround
un argument négatif:Ou pour adhérer à votre format:
la source
dateutils.dround '2018-11-12 13:55' -15m
produit2018-11-12T13:15:00
pas2018-11-12T13:45:00
./-15m
, c'est-à-dire arrondir au multiple de 15 minutes suivant l'heure. Cette fonction a la syntaxe plus lourde , car il accepte moins de valeurs, / -13m n'est pas possible , par exemple , parce que 13 n'est pas un diviseur de 60 minutes (à l'heure)dateutils.dround '2018-11-12 12:52:31' /450s /-15m
, merci!Certains shells sont capables de faire le travail sans appeler une
date
commande externe :ksh
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "#$((a-a%(15*60)))"
bash
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "$((a-a%(15*60)))"
zsh
zmodload zsh/datetime; a=$EPOCHSECONDS; strftime '%Y-%m-%d %H:%M' $((a-a%(15*60)))
Les trois ci-dessus fournissent l'heure locale (pas UTC). Utilisez un TZ = UTC0 de tête si nécessaire.
La syntaxe ksh et bash est presque identique (sauf pour le nécessaire
#
dans ksh). Les zsh nécessitent de charger un module (inclus avec la distribution zsh).Il est également possible de le faire avec (GNU) awk:
rester bouche bée
awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'
Cela fournit un résultat UTC (remplacez le dernier
1
par0
) si local est nécessaire. Mais le chargement d'un awk externe ou d'un module zsh externe peut être aussi lent que l'appel de date lui-même:gnu-date
a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
Un petit exécutable comme
busybox
pourrait fournir des résultats similaires:busybox-date
a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
Notez que le premier mot de la boîte occupée peut être omis si la boîte occupée est liée à ces noms dans un répertoire du CHEMIN.
Les deux
date
etbusybox date
au - dessus imprimeront les heures UTC. Supprimez l'-u
option pour les heures locales.Si votre système d'exploitation a une version de date plus limitée (et c'est ce que vous devez utiliser), essayez:
Ou, si dans FreeBSD, essayez:
la source
Si vous pouvez vivre avec la date d'appel deux fois, celle-ci fonctionne en bash sur Solaris:
Modifié au nom du commentaire pour:
la source
Je ne suis pas sûr de vos besoins exacts. Cependant, si vous souhaitez générer le temps après 15 min, vous pouvez utiliser quelque chose comme
date -d '+15 min'
. La sortie est illustrée ci-dessous:la source