Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

uptime | sed -E 's/^.+([0-9]+ days).+$/\1/'

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

I think this is simplest solution:

uptime | awk '{print $3}'

uptime | awk '{print $3}'

10

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.

uptime=$(</proc/uptime) ;  uptime=${uptime%%.*} ; days=$(( uptime/60/60/24 )); echo $days days
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

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

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

Result:

15 days,

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

This works for me:

$ uptime | grep -o "[0-9]* days"
70 days
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top