Metode berikut membuatnya tidak perlu menelepon date
dua kali.
Overhead panggilan sistem dapat membuat perintah "sederhana" 100 kali lebih lambat daripada bash melakukan hal yang sama di lingkungan lokalnya sendiri.
UPDATE Hanya menyebutkan singkat tentang komentar saya di atas: "100 kali lebih lambat". Sekarang dapat membaca " 500 kali lebih lambat" ... Saya baru-baru ini jatuh (tidak, berjalan membabi buta) ke dalam masalah ini. di sini adalah tautannya: Cara cepat untuk membuat file uji
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
atau
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
Kedua versi hanya akan kembali
2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45
Ini yang pertama dengan loop TEST untuk semua 60 nilai {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
ataused
dan juga bahwa "tidak perlu"cat
vs <file membuat perbedaan run-time aktual yang dramatis. ketika perulangan, seperti dalam contoh "500 kali lebih lambat" saya .. Jadi sepertinya menggunakan shell sedapat mungkin, dan memungkinkan program sepertidate
untuk proses batch adalah apa yang saya maksud .. misalnya. Contoh Gilles 'Left-Pad-0, vs printfInilah cara untuk bekerja pada tanggal di shell. Panggilan pertama
date
untuk mendapatkan komponen, dan mengisi parameter posisi ($1
,$2
dll) dengan komponen (perhatikan bahwa ini adalah salah satu kasus langka di mana Anda ingin menggunakan di$(…)
luar tanda kutip ganda, untuk memecah string menjadi kata-kata). Kemudian lakukan aritmatika, tes, atau apa pun yang perlu Anda lakukan pada komponen. Akhirnya merakit komponen.Bagian aritmatika bisa sedikit rumit karena cangkang diperlakukan
0
sebagai awalan oktal; misalnya di sini$(($5/15))
akan gagal pada 8 atau 9 menit melewati jam. Karena paling banyak ada satu yang memimpin0
,${5#0}
aman untuk berhitung. Menambahkan 100 dan kemudian melepaskannya1
adalah cara untuk mendapatkan jumlah digit yang tetap dalam output.sumber
Mungkin tidak masalah lagi tetapi Anda bisa mencoba dateutils saya sendiri . Pembulatan (turun) ke menit dilakukan dengan
dround
dan argumen negatif:Atau untuk mematuhi format Anda:
sumber
dateutils.dround '2018-11-12 13:55' -15m
menghasilkan2018-11-12T13:15:00
tidak2018-11-12T13:45:00
./-15m
yaitu dibulatkan ke kelipatan 15 menit berikutnya dalam satu jam. Fitur ini mendapat sintaks yang lebih rumit karena menerima nilai yang lebih sedikit, / -13m tidak mungkin misalnya karena 13 bukan pembagi 60 (menit dalam satu jam)dateutils.dround '2018-11-12 12:52:31' /450s /-15m
, terima kasih!Beberapa shell dapat melakukan pekerjaan tanpa memanggil
date
perintah eksternal :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)))
Tiga di atas menyediakan waktu lokal (bukan UTC). Gunakan TZ terkemuka = UTC0 jika perlu.
Sintaks ksh dan bash hampir identik (kecuali untuk yang diperlukan
#
dalam ksh). Zsh perlu memuat modul (termasuk dengan distribusi zsh).Dimungkinkan juga untuk melakukannya dengan (GNU) awk:
melongo
awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'
Ini memberikan hasil UTC (ubah yang terakhir
1
ke0
) jika lokal diperlukan. Tetapi memuat awk eksternal atau modul zsh eksternal mungkin selambat tanggal panggilan itu sendiri:gnu-date
a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
Seperti dieksekusi kecil
busybox
dapat memberikan hasil yang serupa:busybox-date
a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
Perhatikan bahwa kata busybox terkemuka dapat dihilangkan jika busybox ditautkan ke nama-nama tersebut dalam direktori PATH.
Kedua
date
dan dibusybox date
atas akan mencetak waktu UTC. Hapus-u
opsi untuk waktu lokal.Jika OS Anda memiliki versi tanggal yang lebih terbatas (dan itulah yang harus Anda gunakan) maka cobalah:
Atau, jika di FreeBSD, coba:
sumber
Jika Anda dapat hidup dengan tanggal panggilan dua kali, yang ini bekerja di bash pada Solaris:
Diedit atas nama komentar untuk:
sumber
Tidak yakin dengan kebutuhan pasti Anda. Namun, jika Anda ingin menghasilkan waktu setelah 15 menit, maka Anda dapat menggunakan sesuatu seperti
date -d '+15 min'
. Output ditunjukkan di bawah ini:sumber