从" w"中提取正常运行时间值。命令输出

时间:2017-05-03 22:17:50

标签: linux bash shell uptime

如何从linux下面的命令中获取up的值?

# w
 01:16:08 up 20:29,  1 user,  load average: 0.50, 0.34, 0.30
USER     TTY        LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0     00:57    0.00s  0.11s  0.02s w

# w | grep up
 01:16:17 up 20:29,  1 user,  load average: 0.42, 0.33, 0.29

3 个答案:

答案 0 :(得分:4)

Linux 上,通过/proc/uptime的第一个字段获取正常运行时间<分数 的最简单方法(见man proc):

$ cut -d ' ' -f1 /proc/uptime
350735.47

使用w格式设置与uptimeawk相同的方式格式化该数字:

$ awk '{s=int($1);d=int(s/86400);h=int(s % 86400/3600);m=int(s % 3600 / 60);
       printf "%d days, %02d:%02d\n", d, h, m}' /proc/uptime
4 days, 01:25   # 4 days, 1 hour, and 25 minutes

按要求回答问题 - 解析w 的输出(uptime ,其输出与{{1}相同第一个输出行,其中包含所有感兴趣的信息),也适用于macOS / BSD ,粒度为积分秒:

w解决方案:

perl是一个Bash流程替换,提供<(uptime)的输出作为uptime命令的输入 - 见底部。

perl

这假设$ perl -nle 'print for / up +((?:\d+ days?, +)?[^,]+)/' <(uptime) 4 days, 01:25 是每个显示的最大单位。

  • days告诉Perl逐行处理输入,默认情况下不打印任何输出(perl -nle),在输入时自动从每个输入行剥离尾随换行符,并自动追加一个输出(-n); -l告诉Perl将下一个参数视为要处理的脚本(表达式)。

  • -e告诉Perl输出正则表达式print for /.../内捕获的每个捕获组(...)

    • /.../与文字up +匹配,前面有(至少)一个空格,后跟一个或多个空格(up
    • +是一个非捕获子表达式 - 由于(?:\d+ days?, +)? - 匹配:

      • 一位或多位数(?:
      • 后跟单个空格
      • 后跟文字\d+,后面跟着文字days
      • 尾随s?使整个子表达式可选,因为可能存在或不存在数天的部分。
    • ?匹配1个或多个([^,]+)后续字符,但不包括文字+,) - 这是{{ 1}} part。

    • 整个捕获组 - 外部[^,]因此捕获整个正常运行时表达式 - 无论是仅由hh:mm组成还是由(...)组成 - 并打印出来。

  • hh:mm是Bash process substitution (<(...)) 松散地说,将<n> day/s>的输出呈现为<(uptime)可以通过标准输入读取的(临时的,自我删除的)文件。

答案 1 :(得分:2)

使用gnu sed这样的东西:

$ w |head -n1
 02:06:19 up  3:42,  1 user,  load average: 0.01, 0.05, 0.13

$ w |sed -r '1 s/.*up *(.*),.*user.*/\1/g;q'
3:42

$ echo "18:35:23 up 18 days, 9:08, 6 users,  load average: 0.09, 0.31, 0.41" \
|sed -r '1 s/.*up *(.*),.*user.*/\1/g;q'
18 days, 9:08

答案 2 :(得分:0)

鉴于正常运行时间的格式取决于它是否少于或超过24小时,我能想到的最好是双awk

$ w
 18:35:23 up 18 days, 9:08, 6 users,...
$ w | awk -F 'user|up ' 'NF > 1 {print $2}' \
    | awk -F ','       '{for(i = 1; i < NF; i++) {printf("%s ",$i)}} END{print ""}'
18 days   9:08