[英]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
以与w
和uptime
相同的方式格式化该数字:
$ 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: 是非捕获子表达式-由于
?:
-与以下内容匹配:
\\d+
) \\d+
) day
, optionally followed by a literal s
( s?
) day
,然后可以选择跟以文字s
( s?
) ?
?
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.