Showing only the uptime from uptime [unix]
Asked Answered
K

10

5

I'd like to trim the output from uptime

20:10  up 23 days,  3:28, 3 users, load averages: 3.84 1.06 0.64

so that it just shows:

23 days

I've tried using sed, but I'm not sure it's the right tool for the job, and don't have much experience using it.

How can I achieve the output I want?

Keynes answered 15/11, 2009 at 20:13 Comment(0)
I
15

Consider using cut.

uptime | tr "," " " | cut -f6-8 -d" "

seems to work on my MacBook. Here I've also used tr to kill an extraneous ",". There is a bit of an issue with different formats for short and long uptimes.


A possible sed solution:

uptime | sed 's/.*up \([^,]*\), .*/\1/'

which doesn't rely on the string "days" appearing in the output of uptime.

Invent answered 15/11, 2009 at 20:15 Comment(4)
Wasn't me who downvoted... both seem logical - maybe they were just in a bad mood!Keynes
Drive by downvotes happen. I just like to know if my solution is broken.Invent
Didn't work for me on Arch Linux. Sorry I forgot to comment after down-voting.Loophole
@icco: With more info I might be able to fix it, but the gory details of the output from the "standard" utilities can vary from unix to unix, so this kinds of pipelines sometimes need tweaking...Invent
S
5
uptime | sed -E 's/^.+([0-9]+ days).+$/\1/'
Sanjuana answered 15/11, 2009 at 20:15 Comment(2)
\1 means the first captured group (which is in parentheses).Sanjuana
Note that when the substring days is not present (when a reboot has happened less than a day ago), this solution won't work.Broadspectrum
V
5

You can just use the shell without any external tools

$ var="20:10  up 23 days,  3:28, 3 users, load averages: 3.84 1.06 0.64"
$ var=${var/#*up}
$ echo ${var%%,*}
23 days
Verticillate answered 16/11, 2009 at 6:0 Comment(3)
That's clever - didn't know you could do that!Keynes
Nice. I knew, in theory, but I never remember to use the bash extensions. (and it might be worth noting that this won't work with all shells...)Invent
The original bourne shell, csh, don't know about ksh...all of unix doesn't run bash.Invent
M
5

The above solutions only display either the days or the hours. I realize that's what the OP was looking for but I was looking for including hours and minutes also. This displays both the days and hours/minutes when the system has been on for more than a day or just the hours when it's been less than one day:

uptime | sed 's/^.* up \+\(.\+\), \+[0-9] user.*$/\1/'

Props to black belt regex ninja Zach W for getting this working.

Mucus answered 16/4, 2013 at 15:56 Comment(2)
For a single user, the uptime output is "1 user", so it doesn't match "users" (plural) in the above. Change it to just "user" and it seems to work.Papaveraceous
To match user or users you could alter the end of the regular expression to be ...users?.*$. However, as .*$ matches everything to the end of the line just omitting the s, as @PeterGibson suggests, to give ...user.*$ should work.Alverson
R
4

I think this is simplest solution:

uptime | awk '{print $3}'

10

Rosati answered 2/12, 2014 at 17:20 Comment(0)
C
3
uptime=$(</proc/uptime) ;  uptime=${uptime%%.*} ; days=$(( uptime/60/60/24 )); echo $days days
Christmann answered 27/10, 2013 at 19:1 Comment(1)
This is the only solution that uses /proc/uptime to get a consistens data format in the first place.Unexceptionable
H
1

uptime's output usually has "x days, y min" or "x days, y:z" - but sometimes if the uptime is less than a day, it has the hours/minutes as the first time-based output and doesn't bother with the number of days. The rest of the output is very consistent in terms of the number of columns. As a result of that, personally I've been using sed to just remove the last four columns:

$ uptime | sed -e 's/^ [^ ]* up \(.*\)\(,[^,]*\)\{4\}$/\1/'
31 days, 35 min

Alternatively, if you want just the most significant data, you can use a similar method others have mentioned where you just get the first bit of data. With less than a day, this would result in <y> min or <y>:<z>. With more than a day, it would result in <x> days.

$ uptime | sed -e 's/^ [^ ]* up \([^,]*\).*/\1/'
31 days

Lastly, if you want to reflect zero when it is less than 24 hours, you also have the option of using some math on /proc/uptime using bc or shell expressions:

$ uptime
 13:58:41 up 31 days, 55 min,  9 users,  load average: 0.80, 0.89, 0.81
$ echo $(( $(awk -F . '{print $1}' /proc/uptime) / 86400)) days
31 days

$ uptime
 13:59:01 up 21:18,  1 user,  load average: 0.00, 0.00, 0.00
$ echo $(( $(awk -F . '{print $1}' /proc/uptime) / 86400)) days
0 days
Hadley answered 19/7, 2018 at 12:11 Comment(0)
C
1

This works for me:

$ uptime | grep -o "[0-9]* days"
70 days
Cosignatory answered 19/7, 2018 at 12:21 Comment(1)
this should be higher upChampion
T
0
uptime | cut -d',' -f 1 | cut -d 'p' -f 2-

If there are n days since the last reboot it will print n days. It will print a time in hh:mm should the uptime be less than a day.

$ uptime
12:20  up  1:36, 1 user, load averages: 2.75 2.63 2.26
$ uptime | cut -d',' -f 1 | cut -d 'p' -f 2-
  1:36
Tibetan answered 15/3, 2016 at 16:22 Comment(0)
Y
0

Above answers are correct, but if any of you wanted to use awk then use:

uptime | awk '{ print $3,$4 }'

Result:

15 days,
Yearning answered 7/1, 2018 at 21:39 Comment(1)
If uptime is less than a day, this will output something like 5:04, 1 reflecting 5 hours, 4 minutes, and one user logged in.Hadley

© 2022 - 2024 — McMap. All rights reserved.