I'm using uptime in bash in order to get the current runtime of the machine. I need to grab the time and display a format like 2 days, 12 hours, 23 minutes.
-
http://unix.stackexchange.com/questions/34017/convert-linux-sysuptime-to-well-format-date – Etan Reisner Feb 05 '15 at 20:31
-
5With a recent procps, you can use `uptime -p`. This appeared somewhere between 3.3.4 and 3.3.9. – Wintermute Feb 05 '15 at 20:41
8 Answers
My uptime
produces output that looks like:
$ uptime
12:49:10 up 25 days, 21:30, 28 users, load average: 0.50, 0.66, 0.52
To convert that to your format:
$ uptime | awk -F'( |,|:)+' '{print $6,$7",",$8,"hours,",$9,"minutes."}'
25 days, 21 hours, 34 minutes.
How it works
-F'( |,|:)+'
awk divides its input up into fields. This tells awk to use any combination of one or more of space, comma, or colon as the field separator.
print $6,$7",",$8,"hours,",$9,"minutes."
This tells awk to print the sixth field and seventh fields (separated by a space) followed by a comma, the 8th field, the string
hours,
the ninth field, and, lastly, the stringminutes.
.
Handling computers with short uptimes using sed
Starting from a reboot, my uptime
produces output like:
03:14:20 up 1 min, 2 users, load average: 2.28, 1.29, 0.50
04:12:29 up 59 min, 5 users, load average: 0.06, 0.08, 0.48
05:14:09 up 2:01, 5 users, load average: 0.13, 0.10, 0.45
03:13:19 up 1 day, 0 min, 8 users, load average: 0.01, 0.04, 0.05
04:13:19 up 1 day, 1:00, 8 users, load average: 0.02, 0.05, 0.21
12:49:10 up 25 days, 21:30, 28 users, load average: 0.50, 0.66, 0.52
The following sed
command handles these formats:
uptime | sed -E 's/^[^,]*up *//; s/, *[[:digit:]]* users.*//; s/min/minutes/; s/([[:digit:]]+):0?([[:digit:]]+)/\1 hours, \2 minutes/'
With the above times, this produces:
1 minutes
59 minutes
2 hours, 1 minutes
1 day, 0 minutes
1 day, 1 hours, 0 minutes
25 days, 21 hours, 30 minutes
How it works
-E
turns on extended regular expression syntax. (On older GNU seds, use-r
in place of-E
)s/^[^,]*up *//
This substitutes command removes all text up to
up
.s/, *[[:digit:]]* users.*//
This substitute command removes the user count and all text which follows it.
s/min/minutes/
This replaces
min
withminutes
.s/([[:digit:]]+):0?([[:digit:]]+)/\1 hours, \2 minutes/'
If the line contains a time in the hh:mm format, this separates the hours from the minutes and replaces it with
hh hours, mm minutes
.
Handling computers with short uptimes using awk
uptime | awk -F'( |,|:)+' '{d=h=m=0; if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
On the same test cases as above, this produces:
0 days, 0 hours, 1 minutes.
0 days, 0 hours, 59 minutes.
0 days, 2 hours, 1 minutes.
1 days, 0 hours, 0 minutes.
1 days, 1 hours, 0 minutes.
25 days, 21 hours, 30 minutes.
For those who prefer awk code spread out over multiple lines:
uptime | awk -F'( |,|:)+' '{
d=h=m=0;
if ($7=="min")
m=$6;
else {
if ($7~/^day/) { d=$6; h=$8; m=$9}
else {h=$6;m=$7}
}
}
{
print d+0,"days,",h+0,"hours,",m+0,"minutes."
}'

- 109,961
- 14
- 137
- 171
-
1Thanks for the awk solution. One small improvement when piping a file with several uptimes into it, I needed to reset the variables: `cat filewithuptimes.log | awk -F'( |,|:)+' 'd=0; h=0; m=0; {if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'` – mrvulcan Jun 05 '19 at 22:22
-
@mrvulcan Good observation! I just updated the answer to initialize those variables so that the case of multiple input lines is handled. Thanks. – John1024 Jun 05 '19 at 23:03
Just vor completeness... what's about:
$ uptime -p
up 2 weeks, 3 days, 14 hours, 27 minutes

- 461
- 5
- 10
-
7Should be an accepted answer. Works for me on ubuntu, but doesn't work for OSX. – SerCe Dec 12 '16 at 00:09
-
1This is great for ubuntu but does not work on redhat. For that @John answer is great. – Eden Aug 21 '18 at 07:41
Solution: In order to get the linux uptime in seconds, Go to bash and type cat /proc/uptime
.Parse the first number and convert it according to your requirement.
From RedHat documentation:
This file contains information detailing how long the system has been on since its last restart. The output of
/proc/uptime
is quite minimal:350735.47 234388.90
The First number is the total number of seconds the system has been up.
The Second number is how much of that time the machine has spent idle, in seconds.

- 12,197
- 3
- 67
- 61
-
1Keep in mind that this is Linux specific-- it won't work on other POSIX operating systems (unless they're designed to mimic Linux) – LostEth0 Apr 30 '21 at 20:59
-
What is the Operating System that is POSIX, but not Linux, that you have in mind? – R. W. Prado Sep 29 '21 at 04:21
-
I made a universal shell script, for systems which support uptime -p
like newer linux and for those that don't, like Mac OS X.
#!/bin/sh
uptime -p >/dev/null 2>&1
if [ "$?" -eq 0 ]; then
# Supports most Linux distro
# when the machine is up for less than '0' minutes then
# 'uptime -p' returns ONLY 'up', so we need to set a default value
UP_SET_OR_EMPTY=$(uptime -p | awk -F 'up ' '{print $2}')
UP=${UP_SET_OR_EMPTY:-'less than a minute'}
else
# Supports Mac OS X, Debian 7, etc
UP=$(uptime | sed -E 's/^[^,]*up *//; s/mins/minutes/; s/hrs?/hours/;
s/([[:digit:]]+):0?([[:digit:]]+)/\1 hours, \2 minutes/;
s/^1 hours/1 hour/; s/ 1 hours/ 1 hour/;
s/min,/minutes,/; s/ 0 minutes,/ less than a minute,/; s/ 1 minutes/ 1 minute/;
s/ / /; s/, *[[:digit:]]* users?.*//')
fi
echo "up $UP"
Referenced John1024 answer with my own customizations.

- 41
- 1
- 3
-
Perfect for what I needed, and +1 for proper singular-value formatting :) – Matt Jun 04 '20 at 20:50
For this:
- 0 days, 0 hours, 1 minutes.
- 0 days, 0 hours, 59 minutes.
- 0 days, 2 hours, 1 minutes.
- 1 days, 0 hours, 0 minutes.
- 1 days, 1 hours, 0 minutes.
- 25 days, 21 hours, 30 minutes
More simple is:
uptime -p | cut -d " " -f2-

- 29
- 1
-
this doesn’t print anything like “0 days”, at least not with uptime from procps-ng 3.3.16. – dessert Dec 18 '20 at 07:47
For the sake of variety, here's an example with sed:
My raw output:
$ uptime
15:44:56 up 3 days, 22:58, 7 users, load average: 0.48, 0.40, 0.31
Converted output:
$uptime|sed 's/.*\([0-9]\+ days\), \([0-9]\+\):\([0-9]\+\).*/\1, \2 hours, \3 minutes./'
3 days, 22 hours, 58 minutes.

- 919
- 7
- 22
This answer is pretty specific for the uptime
shipped in OS X, but takes into account any case of output.
#!/bin/bash
INFO=`uptime`
echo $INFO | awk -F'[ ,:\t\n]+' '{
msg = "↑ "
if ($5 == "day" || $5 == "days") { # up for a day or more
msg = msg $4 " " $5 ", "
n = $6
o = $7
} else {
n = $4
o = $5
}
if (int(o) == 0) { # words evaluate to zero
msg = msg int(n)" "o
} else { # hh:mm format
msg = msg int(n)" hr"
if (n > 1) { msg = msg "s" }
msg = msg ", " int(o) " min"
if (o > 1) { msg = msg "s" }
}
print "[", msg, "]"
}'
Some example possible outputs:
22:49 up 24 secs, 2 users, load averages: 8.37 2.09 0.76
[ ↑ 24 secs ]
22:50 up 1 min, 2 users, load averages: 5.59 2.39 0.95
[ ↑ 1 min ]
23:39 up 51 mins, 3 users, load averages: 2.18 1.94 1.74
[ ↑ 51 mins ]
23:54 up 1:06, 3 users, load averages: 3.67 2.57 2.07
[ ↑ 1 hr, 6 mins ]
16:20 up 120 days, 10:46, 3 users, load averages: 1.21 2.88 0.80
[ ↑ 120 days, 10 hrs, 46 mins ]

- 2,820
- 2
- 24
- 37
uptime_minutes() {
set `uptime -p`
local minutes=0
shift
while [ -n "$1" ]; do
case $2 in
day*)
((minutes+=$1*1440))
;;
hour*)
((minutes+=$1*60))
;;
minute*)
((minutes+=$1))
;;
esac
shift
shift
done
echo $minutes
}