Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bash format uptime to show days, hours, minutes

Tags:

linux

bash

uptime

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.

like image 783
user1799031 Avatar asked Feb 05 '15 20:02

user1799031


People also ask

How do I get uptime in bash?

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.

How is uptime displayed?

The uptime is normally displayed in days, hours, and minutes as appropriate.

What is uptime in bash?

The uptime command gives you information about the current time, online users, how long your system has been up and running, and the system load average.


1 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 string minutes..

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 with minutes.

  • 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."
    }'
like image 118
John1024 Avatar answered Oct 14 '22 21:10

John1024