简体   繁体   English

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

[英]Extract the uptime value from “w” command output

How can I get the value of up from below command on linux? 如何在Linux up从以下命令获取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

On Linux , the easiest way to get the uptime in (fractional) seconds is via the 1st field of /proc/uptime (see man proc ): Linux上,以获得(分数) 运行时间最简单的方法是通过的第一个领域/proc/uptime (见man proc ):

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

To format that number the same way that w and uptime do, using awk : 使用awk以与wuptime相同的方式格式化该数字:

$ 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

To answer the question as asked - parsing the output of w ( or uptime , whose output is the same as w 's 1st output line, which contains all the information of interest), which also works on macOS/BSD , with a granularity of integral seconds: 要按要求回答问题- 解析w的输出uptime ,其输出与w的第一个输出行相同,其中包含所有感兴趣的信息),它也适用于macOS / BSD ,粒度为积分秒:

A perl solution: perl解决方案:

<(uptime) is a Bash process substitution that provides uptime 's output as input to the perl command - see bottom. <(uptime)是Bash进程的替代品,它提供uptime的输出作为perl命令的输入-参见底部。

$ perl -nle 'print for / up +((?:\d+ days?, +)?[^,]+)/' <(uptime)
4 days, 01:25

This assumes that days is the largest unit every displayed. 假设days是每个显示的最大单位。

  • perl -nle tells Perl to process the input line by line, without printing any output by default ( -n ), automatically stripping the trailing newline from each input line on input, and automatically appending one on output ( -l ); perl -nle告诉Perl perl -nle处理输入,默认情况下不打印任何输出( -n ),自动从输入的每个输入行中perl -nle尾随换行符,并自动在输出后附加一个( -l ); -e tells Perl to treat the next argument as the script (expression) to process. -e告诉Perl将下一个参数视为要处理的脚本(表达式)。

  • print for /.../ tells Perl to output what each capture group (...) inside regex /.../ captures. print for /.../告诉Perl输出正则表达式/.../捕获中的每个捕获组(...)

    • up + matches literal up , preceded by (at least) one space and followed by 1 or more spaces ( + ) up +匹配文字up ,前面(至少)一个空格,再后面一个或多个空格( +
    • (?:\\d+ days?, +)? is a non-capturing subexpression - due to ?: - that matches: 是非捕获子表达式-由于?: -与以下内容匹配:

      • 1 or more digits ( \\d+ ) 1个或多个数字( \\d+
      • followed by a single space 跟一个空格
      • followed by literal day , optionally followed by a literal s ( s? ) 紧随其后的是文字day ,然后可以选择跟以文字ss?
      • the trailing ? 尾随? makes the entire subexpression optional , given that a number-of-days part may or may not be present. 考虑到可能存在或不存在天数部分,因此使整个子表达式为可选
    • [^,]+ matches 1 or more ( + ) subsequent characters up to, but not including a literal , ( [^,] ) - this is the hh:mm part. [^,]+匹配1个或多个( + )后面的字符为止,但不包括文字,[^,] ) -这是hh:mm部分。

    • The overall capture group - the outer (...) therefore captures the entire up-time expression - whether composed of hh:mm only, or preceded by <n> day/s> - and prints that. 整个捕获组-外部(...)捕获整个正常运行时间表达式-无论是仅由hh:mm组成,还是由<n> day/s>开头-并进行打印。

  • <(uptime) is a Bash process substitution ( <(...) ) that, loosely speaking, presents uptime 's output as a (temporary, self-deleting) file that perl can read via stdin. <(uptime)是Bash 进程的替代项( <(...) ,从广义上讲,将uptime的输出显示为perl可以通过stdin读取的(临时,自删除)文件。

Something like this with gnu sed: 用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

Given that the format of the uptime depends on whether it is less or more than 24 hours, the best I could come up with is a double awk : 鉴于正常运行时间的格式取决于它是少于还是超过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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM