Poniższe metody sprawiają, że nie trzeba dzwonić date
dwukrotnie.
Narzut wywołania systemowego może wykonać „proste” polecenie 100 razy wolniej niż bash, robiąc to samo w swoim lokalnym środowisku.
AKTUALIZACJA Krótka wzmianka o moim powyższym komentarzu: „100 razy wolniej”. Teraz można odczytać „ 500 razy wolniej” ... Niedawno wpadłem (nie, szedłem na oślep) do tego właśnie problemu. tutaj jest link: Szybki sposób na zbudowanie pliku testowego
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
lub
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
Obie wersje zostaną zwrócone tylko
2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45
Oto pierwszy z pętlą TEST dla wszystkich 60 wartości {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
lubsed
, a także, że „niepotrzebne”cat
vs <plik robi dramatyczną rzeczywistą różnicę czasu wykonywania. podczas zapętlania, jak w moim przykładzie „500 razy wolniejszym”. Wydaje się, że używanie powłoki tam, gdzie to możliwe, i pozwalanie programowi takiemu jakdate
proces wsadowy, mam na myśli… np. Przykład Gillesa Left-Pad-0, a printfOto sposób pracy nad datami w powłoce. Najpierw wywołaj,
date
aby pobrać komponenty i wypełnić parametry pozycji ($1
,$2
itp.) Komponentami (zauważ, że jest to jeden z tych rzadkich przypadków, w których chcesz użyć$(…)
poza podwójnymi cudzysłowami, aby rozbić ciąg na słowa). Następnie wykonaj arytmetykę, testy lub cokolwiek innego, co musisz zrobić na komponentach. Na koniec zmontuj elementy.Część arytmetyczna może być nieco trudna, ponieważ powłoki traktują
0
jak ośmiokrotny przedrostek; na przykład tutaj$(($5/15))
nie powiedzie się o 8 lub 9 minut po godzinie. Ponieważ jest co najwyżej jeden wiodący0
,${5#0}
jest bezpieczny dla arytmetyki. Dodanie 100, a następnie usunięcie,1
jest sposobem na uzyskanie stałej liczby cyfr na wyjściu.źródło
Może to już nie ma znaczenia, ale możesz wypróbować moje własne dateutils . Zaokrąglanie (w dół) do minut odbywa się za
dround
pomocą argumentu ujemnego:Lub zastosować się do swojego formatu:
źródło
dateutils.dround '2018-11-12 13:55' -15m
produkuje .2018-11-12T13:15:00
2018-11-12T13:45:00
/-15m
tj. Zaokrąglić w dół do następnej wielokrotności 15 minut w ciągu godziny. Ta funkcja ma bardziej nieporęczną składnię, ponieważ akceptuje mniej wartości, / -13 m nie jest możliwe, na przykład ponieważ 13 nie jest dzielnikiem 60 (minut na godzinę)dateutils.dround '2018-11-12 12:52:31' /450s /-15m
, dzięki!Niektóre powłoki są w stanie wykonać pracę bez wywoływania zewnętrznego
date
polecenia: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)))
Trzy powyższe zapewniają czas lokalny (nie UTC). W razie potrzeby użyj wiodącego TZ = UTC0.
Składnia ksh i bash jest prawie identyczna (z wyjątkiem wymaganej
#
w ksh). Zsh wymaga załadowania modułu (zawartego w dystrybucji zsh).Można to również zrobić za pomocą awk (GNU):
gapić się
awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'
Zapewnia to wynik UTC (zmień ostatni
1
na0
), jeśli lokalny jest potrzebny. Ale ładowanie zewnętrznego awk lub zewnętrznego modułu zsh może być tak wolne jak sama data wywołania:data gnu
a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
Mały plik wykonywalny, taki jak,
busybox
może zapewnić podobne wyniki:busy-date
a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
Zauważ, że wiodące słowo busybox może zostać pominięte, jeśli busybox jest powiązany z tymi nazwami w katalogu ŚCIEŻKI.
Zarówno wyżej, jak
date
ibusybox date
wyżej będą drukować czasy UTC. Usuń-u
opcję czasu lokalnego.Jeśli twój system operacyjny ma bardziej ograniczoną wersję daty (i właśnie tego musisz użyć), spróbuj:
Lub, jeśli we FreeBSD, spróbuj:
źródło
Jeśli możesz dwa razy żyć z datą dzwonienia, ta działa bash na Solarisie:
Edytowane w imieniu komentarza do:
źródło
Nie jestem pewien dokładnych wymagań. Jeśli jednak chcesz wygenerować czas po 15 minutach, możesz użyć czegoś takiego
date -d '+15 min'
. Dane wyjściowe pokazano poniżej:źródło