Bash формат uptime, чтобы показать дни, часы, минуты

Я использую uptime в bash, чтобы получить текущую среду выполнения машины. Мне нужно захватить время и отобразить формат как 2 дня, 12 часов, 23 минуты.

5 ответов


мой uptime производит вывод, который выглядит так:

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

преобразовать в свой формат:

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

как это работает

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

    awk делит свой вход на поля. Это говорит awk использовать любую комбинацию одного или нескольких пробелов, запятой или двоеточием в качестве разделителя полей.

  • print ,",",,"hours,",,"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:]]+)/ hours,  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 seds используйте -r на месте -E)

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

    эта команда замены удаляет весь текст до up.

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

    эта команда замены удаляет количество пользователей и весь текст, который следует за ним.

  • s/min/minutes/

    этот заменяет min С minutes.

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

    если строка содержит время в формате hh: mm, это отделяет часы от минут и заменяет его на hh hours, mm minutes.

обработка компьютеров с коротким временем безотказной работы с помощью awk

uptime | awk -F'( |,|:)+' '{if (=="min") m=; else {if (~/^day/) {d=;h=;m=} else {h=;m=}}} {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'( |,|:)+' '{
    if (=="min")
        m=;
    else {
        if (~/^day/) { d=; h=; m=}
        else {h=;m=}
        }
    }
    {
        print d+0,"days,",h+0,"hours,",m+0,"minutes."
    }'

просто vor полноты... как насчет:

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

для разнообразия, вот пример с 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]\+\).*/,  hours,  minutes./'
3 days, 22 hours, 58 minutes.

для этого:

  • 0 дней, 0 часов, 1 минут.
  • 0 дней, 0 часов, 59 минут.
  • 0 дней, 2 часа, 1 минута.
  • 1 день, 0 часов, 0 минут.
  • 1 день, 1 час, 0 минут.
  • 25 дней, 21 час, 30 минут

проще:
uptime -p | cut -d " " -f2-


этот ответ довольно специфичен для uptime поставляется в OS X, но учитывает любой случай вывода.

#!/bin/bash

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

            n = 
            o = 
        } else {
            n = 
            o = 
        }

        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 ]