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 ,",",,"hours,",,"minutes."}'
25 days, 21 hours, 34 minutes.
工作原理
-F'( |,|:)+'
awk 将其输入分成字段。这告诉 awk 使用 space、逗号或冒号中的一个或多个的任意组合作为字段分隔符。
print ,",",,"hours,",,"minutes."
这告诉 awk 打印第六个字段和第七个字段(由 space 分隔)后跟一个逗号,第 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'( |,|:)+' '{d=h=m=0; 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'( |,|:)+' '{
d=h=m=0;
if (=="min")
m=;
else {
if (~/^day/) { d=; h=; m=}
else {h=;m=}
}
}
{
print d+0,"days,",h+0,"hours,",m+0,"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.
为了完整性...关于:
$ uptime -p
up 2 weeks, 3 days, 14 hours, 27 minutes
这个答案对于 OS X 中的 uptime
非常具体,但考虑到了输出的任何情况。
#!/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 ]
为此:
- 0 天 0 小时 1 分钟。
- 0 天 0 小时 59 分钟。
- 0 天 2 小时 1 分钟。
- 1 天 0 小时 0 分钟。
- 1 天 1 小时 0 分钟。
- 25 天 21 小时 30 分钟
更简单的是:
uptime -p | cut -d " " -f2-
我制作了一个通用的 shell 脚本,用于支持 uptime -p
的系统,如更新的 linux 和不支持的系统,如 Mac OS X.
#!/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 }')
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:]]+)/ hours, 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 的回答,自己定制。
uptime_minutes() {
set `uptime -p`
local minutes=0
shift
while [ -n "" ]; do
case in
day*)
((minutes+=*1440))
;;
hour*)
((minutes+=*60))
;;
minute*)
((minutes+=))
;;
esac
shift
shift
done
echo $minutes
}
解决方案:为了以秒为单位获得 linux 正常运行时间,转到 bash 并键入 cat /proc/uptime
。解析第一个数字并根据您的要求进行转换。
来自 RedHat documentation:
This file contains information detailing how long the system has been on since its last restart. The output of /proc/uptime
is quite minimal:
350735.47 234388.90
The First number is the total number of seconds the system has been
up.
The Second number is how much of that time the machine has spent
idle, in
seconds.
我在 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 ,",",,"hours,",,"minutes."}'
25 days, 21 hours, 34 minutes.
工作原理
-F'( |,|:)+'
awk 将其输入分成字段。这告诉 awk 使用 space、逗号或冒号中的一个或多个的任意组合作为字段分隔符。
print ,",",,"hours,",,"minutes."
这告诉 awk 打印第六个字段和第七个字段(由 space 分隔)后跟一个逗号,第 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'( |,|:)+' '{d=h=m=0; 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'( |,|:)+' '{
d=h=m=0;
if (=="min")
m=;
else {
if (~/^day/) { d=; h=; m=}
else {h=;m=}
}
}
{
print d+0,"days,",h+0,"hours,",m+0,"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.
为了完整性...关于:
$ uptime -p
up 2 weeks, 3 days, 14 hours, 27 minutes
这个答案对于 OS X 中的 uptime
非常具体,但考虑到了输出的任何情况。
#!/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 ]
为此:
- 0 天 0 小时 1 分钟。
- 0 天 0 小时 59 分钟。
- 0 天 2 小时 1 分钟。
- 1 天 0 小时 0 分钟。
- 1 天 1 小时 0 分钟。
- 25 天 21 小时 30 分钟
更简单的是:
uptime -p | cut -d " " -f2-
我制作了一个通用的 shell 脚本,用于支持 uptime -p
的系统,如更新的 linux 和不支持的系统,如 Mac OS X.
#!/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 }')
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:]]+)/ hours, 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 的回答,自己定制。
uptime_minutes() {
set `uptime -p`
local minutes=0
shift
while [ -n "" ]; do
case in
day*)
((minutes+=*1440))
;;
hour*)
((minutes+=*60))
;;
minute*)
((minutes+=))
;;
esac
shift
shift
done
echo $minutes
}
解决方案:为了以秒为单位获得 linux 正常运行时间,转到 bash 并键入 cat /proc/uptime
。解析第一个数字并根据您的要求进行转换。
来自 RedHat documentation:
This file contains information detailing how long the system has been on since its last restart. The output of
/proc/uptime
is quite minimal:350735.47 234388.90
The First number is the total number of seconds the system has been up.
The Second number is how much of that time the machine has spent idle, in seconds.