繁体   English   中英

Bash 格式化正常运行时间以显示天、小时、分钟

[英]Bash format uptime to show days, hours, minutes

我在 bash 中使用正常运行时间以获得机器的当前运行时间。 我需要获取时间并显示 2 天 12 小时 23 分钟等格式。

我的uptime产生如下输出:

$ uptime
 12:49:10 up 25 days, 21:30, 28 users,  load average: 0.50, 0.66, 0.52

要将其转换为您的格式:

$ uptime | awk -F'( |,|:)+' '{print $6,$7",",$8,"hours,",$9,"minutes."}'
25 days, 21 hours, 34 minutes.

这个怎么运作

  • -F'( |,|:)+'

    awk 将其输入分成多个字段。 这告诉 awk 使用空格、逗号或冒号中的一个或多个的任意组合作为字段分隔符。

  • print $6,$7",",$8,"hours,",$9,"minutes."

    这告诉 awk 打印第六个字段和第七个字段(由空格分隔),后跟一个逗号、第 8 个字段、字符串hours,第九个字段,最后是字符串minutes. .

使用 sed 处理正常运行时间较短的计算机

从重新启动开始,我的uptime会产生如下输出:

 03:14:20 up 1 min,  2 users,  load average: 2.28, 1.29, 0.50
 04:12:29 up 59 min,  5 users,  load average: 0.06, 0.08, 0.48
 05:14:09 up  2:01,  5 users,  load average: 0.13, 0.10, 0.45
 03:13:19 up 1 day, 0 min,  8 users,  load average: 0.01, 0.04, 0.05
 04:13:19 up 1 day,  1:00,  8 users,  load average: 0.02, 0.05, 0.21
 12:49:10 up 25 days, 21:30, 28 users,  load average: 0.50, 0.66, 0.52

以下sed命令处理这些格式:

uptime | sed -E 's/^[^,]*up *//; s/, *[[:digit:]]* users.*//; s/min/minutes/; s/([[:digit:]]+):0?([[:digit:]]+)/\1 hours, \2 minutes/' 

随着上述时间,这产生:

1 minutes
59 minutes
2 hours, 1 minutes
1 day, 0 minutes
1 day,  1 hours, 0 minutes
25 days, 21 hours, 30 minutes

这个怎么运作

  • -E打开扩展的正则表达式语法。 (在较旧的 GNU sed 上,使用-r代替-E

  • s/^[^,]*up *//

    这个替换命令删除了up所有文本。

  • s/, *[[:digit:]]* users.*//

    此替换命令删除用户计数及其后的所有文本。

  • s/min/minutes/

    这将min替换为minutes

  • s/([[:digit:]]+):0?([[:digit:]]+)/\\1 hours, \\2 minutes/'

    如果该行包含 hh:mm 格式的时间,则会将小时与分钟分开,并将其替换为hh hours, mm minutes

使用 awk 处理正常运行时间较短的计算机

uptime | awk -F'( |,|:)+' '{d=h=m=0; if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'

在与上述相同的测试用例中,这会产生:

0 days, 0 hours, 1 minutes.
0 days, 0 hours, 59 minutes.
0 days, 2 hours, 1 minutes.
1 days, 0 hours, 0 minutes.
1 days, 1 hours, 0 minutes.
25 days, 21 hours, 30 minutes.

对于那些喜欢分散在多行上的 awk 代码的人:

uptime | awk -F'( |,|:)+' '{
    d=h=m=0;
    if ($7=="min")
        m=$6;
    else {
        if ($7~/^day/) { d=$6; h=$8; m=$9}
        else {h=$6;m=$7}
        }
    }
    {
        print d+0,"days,",h+0,"hours,",m+0,"minutes."
    }'

只是 vor 完整性......是关于:

$ uptime -p
up 2 weeks, 3 days, 14 hours, 27 minutes

解决方案:为了以秒为单位获得 linux 正常运行时间,请转到 bash 并键入cat /proc/uptime解析第一个数字并根据您的要求进行转换。

从红帽文档

此文件包含详细说明系统自上次重新启动以来已运行多长时间的信息 /proc/uptime的输出非常小:

 350735.47 234388.90

一个数字是系统启动的总秒数。

第二个数字是机器空闲的时间,以秒为单位。

我为支持uptime -p系统(如较新的 linux)和不支持的系统(如 Mac OS X)制作了一个通用的 shell 脚本。

#!/bin/sh

uptime -p >/dev/null 2>&1

if [ "$?" -eq 0 ]; then
  # Supports most Linux distro
  # when the machine is up for less than '0' minutes then
  # 'uptime -p' returns ONLY 'up', so we need to set a default value
  UP_SET_OR_EMPTY=$(uptime -p | awk -F 'up ' '{print $2}')
  UP=${UP_SET_OR_EMPTY:-'less than a minute'}
else
  # Supports Mac OS X, Debian 7, etc
  UP=$(uptime | sed -E 's/^[^,]*up *//; s/mins/minutes/; s/hrs?/hours/;
  s/([[:digit:]]+):0?([[:digit:]]+)/\1 hours, \2 minutes/;
  s/^1 hours/1 hour/; s/ 1 hours/ 1 hour/;
  s/min,/minutes,/; s/ 0 minutes,/ less than a minute,/; s/ 1 minutes/ 1 minute/;
  s/  / /; s/, *[[:digit:]]* users?.*//')
fi

echo "up $UP"

要旨

使用我自己的自定义引用了 John1024 的答案。

为了这:

  • 0天0小时1分钟。
  • 0 天 0 小时 59 分钟。
  • 0天2小时1分钟。
  • 1天0小时0分钟。
  • 1天1小时0分钟。
  • 25 天 21 小时 30 分钟

更简单的是:
uptime -p | cut -d " " -f2-

为了多样性,这里有一个使用 sed 的例子:

我的原始输出:

$ uptime
15:44:56 up 3 days, 22:58,  7 users,  load average: 0.48, 0.40, 0.31

转换输出:

$uptime|sed 's/.*\([0-9]\+ days\), \([0-9]\+\):\([0-9]\+\).*/\1, \2 hours, \3 minutes./'
3 days, 22 hours, 58 minutes.

这个答案非常特定于 OS X 中提供的uptime ,但考虑了任何输出情况。

#!/bin/bash

INFO=`uptime`
echo $INFO | awk -F'[ ,:\t\n]+' '{
        msg = "↑ "
        if ($5 == "day" || $5 == "days") {      # up for a day or more
            msg = msg $4 " " $5 ", "

            n = $6
            o = $7
        } else {
            n = $4
            o = $5
        }

        if (int(o) == 0) {                      # words evaluate to zero
            msg = msg int(n)" "o
        } else {                                # hh:mm format
            msg = msg int(n)" hr"
            if (n > 1) { msg = msg "s" }

            msg = msg ", " int(o) " min"
            if (o > 1) { msg = msg "s" }
        }

        print "[", msg, "]"
    }'

一些可能的输出示例:

22:49 up 24 secs, 2 users, load averages: 8.37 2.09 0.76
[ ↑ 24 secs ]

22:50 up 1 min, 2 users, load averages: 5.59 2.39 0.95
[ ↑ 1 min ]

23:39 up 51 mins, 3 users, load averages: 2.18 1.94 1.74
[ ↑ 51 mins ]

23:54 up 1:06, 3 users, load averages: 3.67 2.57 2.07
[ ↑ 1 hr, 6 mins ]

16:20 up 120 days, 10:46, 3 users, load averages: 1.21 2.88 0.80
[ ↑ 120 days, 10 hrs, 46 mins ]
uptime_minutes() {
  set `uptime -p`
  local minutes=0

  shift
  while [ -n "$1" ]; do
    case $2 in
      day*)
        ((minutes+=$1*1440))
        ;;
      hour*)
        ((minutes+=$1*60))
        ;;
      minute*)
        ((minutes+=$1))
        ;;
    esac
   shift
   shift
  done

  echo $minutes
}

暂无
暂无

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

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