Có thể dễ dàng định dạng giây như một thời gian có thể đọc được của con người trong bash?
Tôi không muốn định dạng nó là một ngày, nhưng là số ngày / giờ / phút, v.v ...
Có thể dễ dàng định dạng giây như một thời gian có thể đọc được của con người trong bash?
Tôi không muốn định dạng nó là một ngày, nhưng là số ngày / giờ / phút, v.v ...
Câu trả lời:
Bạn có thể sử dụng một cái gì đó như thế này:
function displaytime {
local T=$1
local D=$((T/60/60/24))
local H=$((T/60/60%24))
local M=$((T/60%60))
local S=$((T%60))
(( $D > 0 )) && printf '%d days ' $D
(( $H > 0 )) && printf '%d hours ' $H
(( $M > 0 )) && printf '%d minutes ' $M
(( $D > 0 || $H > 0 || $M > 0 )) && printf 'and '
printf '%d seconds\n' $S
}
Ví dụ:
$ displaytime 11617
3 hours 13 minutes and 37 seconds
$ displaytime 42
42 seconds
$ displaytime 666
11 minutes and 6 seconds
Cách dễ nhất và sạch nhất là lớp lót này (ở đây giả sử GNU date
):
Nếu số giây là, nói:
seconds=123456789 # as in one of the answers above
eval "echo $(date -ud "@$seconds" +'$((%s/3600/24)) days %H hours %M minutes %S seconds')"
-> đầu ra: 1428 days 21 hours 33 minutes 09 seconds
+%T
định dạng cho Giờ: Phút: Giây date +%T "1970-01-01 + ${seconds} seconds"
để có được điều này21:33:09
Tín dụng được chuyển đến Stéphane Gimenez nhưng nếu ai đó chỉ muốn hiển thị giây nếu thời gian ít hơn một phút thì đây là phiên bản sửa đổi của tôi mà tôi sử dụng (cũng với số nhiều cố định):
converts()
{
local t=$1
local d=$((t/60/60/24))
local h=$((t/60/60%24))
local m=$((t/60%60))
local s=$((t%60))
if [[ $d > 0 ]]; then
[[ $d = 1 ]] && echo -n "$d day " || echo -n "$d days "
fi
if [[ $h > 0 ]]; then
[[ $h = 1 ]] && echo -n "$h hour " || echo -n "$h hours "
fi
if [[ $m > 0 ]]; then
[[ $m = 1 ]] && echo -n "$m minute " || echo -n "$m minutes "
fi
if [[ $d = 0 && $h = 0 && $m = 0 ]]; then
[[ $s = 1 ]] && echo -n "$s second" || echo -n "$s seconds"
fi
echo
}
Một ví dụ khác trong POSIX:
converts(){
t=$1
d=$((t/60/60/24))
h=$((t/60/60%24))
m=$((t/60%60))
s=$((t%60))
if [ $d -gt 0 ]; then
[ $d = 1 ] && printf "%d day " $d || printf "%d days " $d
fi
if [ $h -gt 0 ]; then
[ $h = 1 ] && printf "%d hour " $h || printf "%d hours " $h
fi
if [ $m -gt 0 ]; then
[ $m = 1 ] && printf "%d minute " $m || printf "%d minutes " $m
fi
if [ $d = 0 ] && [ $h = 0 ] && [ $m = 0 ]; then
[ $s = 1 ] && printf "%d second" $s || printf "%d seconds" $s
fi
printf '\n'
}
convert $s
để có đầu ra đẹp.
Tôi sẽ làm như thế này:
$ seconds=123456789; echo $((seconds/86400))" days "$(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")
1428 days 21 hours 33 minutes 09 seconds
$
Đây là một lớp lót ở trên, được chia nhỏ để dễ hiểu hơn:
$ seconds=123456789
$ echo $((seconds/86400))" days"\
$(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")
Ở phần trên tôi đang lặp lại đầu ra của một lệnh khác chạy bên trong lệnh $( ... )
phụ. Lệnh phụ đó đang thực hiện việc này, tính toán số ngày (giây / 86400), sau đó sử dụng date
lệnh trong một lệnh phụ khác $(date -d ... )
, để tạo giờ, phút và giây trong một số giây nhất định.
Tôi đã sửa đổi chức năng hiển thị ở trên ... như sau:
seconds2time ()
{
T=$1
D=$((T/60/60/24))
H=$((T/60/60%24))
M=$((T/60%60))
S=$((T%60))
if [[ ${D} != 0 ]]
then
printf '%d days %02d:%02d:%02d' $D $H $M $S
else
printf '%02d:%02d:%02d' $H $M $S
fi
}
bởi vì tôi luôn muốn thấy HH: MM: SS, ngay cả khi chúng là số không.
Tôi đang xây dựng dựa trên câu trả lời của atti mà tôi thích như một ý tưởng.
Bạn có thể làm điều này với BUILTIN bash printf
mà sẽ lấy giây kể từ khi kỷ nguyên như một cuộc tranh cãi. Không cần ngã ba để chạy date
.
Bạn phải đặt múi giờ thành UTC printf
vì nó định dạng thời gian trong múi giờ địa phương của bạn và bạn sẽ nhận được câu trả lời sai nếu bạn không ở trong thời gian UTC.
$ seconds=123456789
$ TZ=UTC printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1428 days 21 hours 33 minutes 09 seconds
Trong giờ địa phương của tôi (hiện tại là NZDT - +1300), câu trả lời là sai nếu tôi không đặt múi giờ
$ seconds=123456789
$ printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1428 days 09 hours 33 minutes 09 seconds
Có và không thiết lập múi giờ
$ seconds=$(( 3600 * 25))
$ printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1 days 13 hours 00 minutes 00 seconds
$ TZ=UTC printf "%d days %(%H hours %M minutes %S seconds)T\n" $((seconds/86400)) $seconds
1 days 01 hours 00 minutes 00 seconds
printf
giới thiệu %(datefmt)T
ký hiệu này bắt đầu bằng bash-4.2-alpha.
Đây một
secs=378444
echo $(($secs/86400))d $(($(($secs - $secs/86400*86400))/3600))h:$(($(($secs - $secs/86400*86400))%3600/60))m:$(($(($secs - $secs/86400*86400))%60))s
Đầu ra:
4d 9h:7m:24s
date --date '@1005454800'
mang lại cho bạn Sun Nov 11 00:00:00 EST 2001
, tức là 1005454800 giây sau kỷ nguyên Unix. Bạn có thể định dạng với tùy chọn ngày + FORMAT.