2

I would like to save the output of the uptime command into a csv file in a Bash script. Since the uptime command has different output formats based on the time since the last reboot I came up with a pretty heavy solution based on case, but there is surely a more elegant way of doing this.

uptime output:

 8:58AM  up 15:12, 1 user, load averages: 0.01, 0.02, 0.00

desired result:

15:12,1 user,0.00 0.02 0.00,

current code:

case "`uptime | wc -w | awk '{print $1}'`" in
#Count the number of words in the uptime output

10)
    #e.g.:  8:16PM  up  2:30, 1 user, load averages: 0.09, 0.05, 0.02
    echo -n `uptime | awk '{ print $3 }' | awk '{gsub ( ",","" ) ; print $0 }'`","`uptime | awk '{ print $4,$5 }' | awk '{gsub ( ",","" ) ; print $0 }'`","`uptime | awk '{ print $8,$9,$10 }' | awk '{gsub ( ",","" ) ; print $0 }'`","
    ;;

12)
    #e.g.: 1:41pm  up 105 days, 21:46,  2 users,  load average: 0.28, 0.28, 0.27
    echo -n `uptime | awk '{ print $3,$4,$5 }' | awk '{gsub ( ",","" ) ; print $0 }'`","`uptime | awk '{ print $6,$7 }' | awk '{gsub ( ",","" ) ; print $0 }'`","`uptime | awk '{ print $10,$11,$12 }' | awk '{gsub ( ",","" ) ; print $0 }'`","
    ;;

13)
    #e.g.: 12:55pm  up 105 days, 21 hrs,  2 users,  load average: 0.26, 0.26, 0.26
    echo -n `uptime | awk '{ print $3,$4,$5,$6 }' | awk '{gsub ( ",","" ) ; print $0 }'`","`uptime | awk '{ print $7,$8 }' | awk '{gsub ( ",","" ) ; print $0 }'`","`uptime | awk '{ print $11,$12,$13 }' | awk '{gsub ( ",","" ) ; print $0 }'`","
    ;;
esac
8

I suggest you go directly to the source instead of parsing uptime(1) output.

  • Uptime is in /proc/uptime
  • Load average is in /proc/loadavg
  • Number of users is a bit more involved, see Wikipedia:utmp, but the w(1) or who(1) commands will help you.

The following is not exactly the desired output you asked for, but you get the idea:

$ echo $(cut -d ' ' -f 1 </proc/uptime),$(w -h | wc -l),$(cut -d ' ' -f 1-3 </proc/loadavg),
8545883.49,4,0.00 0.01 0.05

That means 8.55e6 seconds (almost 99 days), 4 users, load average.

  • 1
    Sorry the question was incorrectly tagged "linux", I am on a FreeBSD system (FreeNAS), but I get your point and the approach would be similar: parsing /sbin/sysctl kern.boottime and /sbin/sysctl vm.loadavg Thanks for the hint! – Keek Aug 23 '14 at 8:01
1

The following code will suits all kind of uptime outputs. Hope this will help you,

uptime=`uptime`
upt=`echo $uptime | grep -ohe 'up .*user*' | awk '{gsub ( "user*","" ); print $0 }' | sed 's/,//g' | sed -r 's/(\S+\s+){1}//' | awk '{$NF=""}1'`
usrs=`echo $uptime | grep -ohe '[0-9.*] user[s,]'| sed 's/,//g'`
ldt=`echo $uptime | grep -ohe 'load average[s:][: ].*' | sed 's/,//g' | awk '{ print $3" "$4" "$5"," }'`
echo $upt, $usrs, $ldt
0

FWIW:

$ echo -e "\n$(uptime)\n" ; uptime \
| sed -nre 's/.+up +([\:0-9]+), +([^ ] [^,]+), +.*: +([^ ]+), +([^ ]+), +([^ ]+)$/\1, \2, \3 \4 \5/p'

 12:58:47 up  5:53,  2 users,  load average: 0,21, 0,09, 0,10

5:53, 2 users, 0,21 0,09 0,10

Note that the decimal separator for numbers depends on your locale settings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.