我正在尝试从 bash 命令输出中提取一些信息:
uptime | awk '{print $3}'
运行它时,我得到以下结果:8:27,
如何删除最后一个符号(即逗号)?
另一个变体(替换和awk
):sed
cut
# "unnecessary" echo with evil backticks to get rid of extra spaces
echo `uptime|cut -d, -f1'
似乎工作......直到正常运行时间达到一天(感谢@sudo_O指出)。然后输出格式将包括天数,我们需要
echo `uptime|cut -d, -f2`
(后者是我最初的答案,因为我测试的正常运行时间 > 24 小时)。
UPD:这两种解决方案都不起作用:后者打印没有天数的正常运行时间,前者无法提取小时数,因为没有天数时它们前面没有逗号分隔符 - 但其余答案实际上由那些证明失败。
整个方法容易出错。几个月和几年后会发生什么?(我似乎记得它仍然显示 N 天,但我可能会出错)。如果正常运行时间是本地化的怎么办?(他们是否因为现有脚本而拒绝这样做?)它为 1 个用户、“1 个用户”或“1 个用户”显示了什么?如果我们知道所有的答案,我们还想依赖它们吗?
如果我们的目的是向用户显示正常运行时间,那么使用正则表达式提取“up”和“users”之间的部分就可以了:
uptime | sed 's/^.*up\(.*\), *[0-9]\+ *users.*$/\1/'
如果我们想比较时间或收集统计数据,像 Linux 特定的东西/proc/uptime
会更好(第一列/proc/uptime
是原始正常运行时间秒数)。
你几乎拥有它,只是substr
orgsub
函数awk
$ uptime | awk '{print substr($3,1,length($3)-1)}'
2:49
$ uptime | awk '{sub(/,/,"");print $3}'
2:49
不需要过多的管道或不正确地使用反引号。
使用(GNU)uptime
给定不同的输出,更好更健壮的解决方案: grep -Po "\d{1,2}:\d{2}(?=,)"
# More than one day
$ uptime
12:46:18 up 92 days, 5:00, 2 users, load average: 0.00, 0.01, 0.05
$ uptime | grep -Po "\d{1,2}:\d{2}(?=,)"
5:00
# Less than one day
$ uptime
12:47:30 up 4:24, 7 users, load average: 0.34, 0.12, 0.07
$ uptime | grep -Po "\d{1,2}:\d{2}(?=,)"
4:24
或与sed -rn 's/.*([0-9]{1,2}:[0-9]{2}),.*/\1/p
:
# More than one day
$ uptime
12:54:00 up 92 days, 5:07, 2 users, load average: 0.03, 0.02, 0.05
$ uptime | sed -rn 's/.*([0-9]{1,2}:[0-9]{2}),.*/\1/p'
5:07
# Less than one day
$ uptime
12:54:55 up 4:31, 7 users, load average: 0.07, 0.10, 0.08
$ uptime | sed -rn 's/.*([0-9]{1,2}:[0-9]{2}),.*/\1/p'
4:31
更新:所以如果uptime
不到一个小时,输出是否再次不同!?
$ uptime
14:46:03 up 3 min, 4 users, load average: 0.54, 0.75, 0.36
$ uptime
14:53:40 up 11 min, 4 users, load average: 0.48, 0.62, 0.46
一个regexp
统治他们的人:
$ sed -rn 's/.*up\s+(.*),\s+[0-9]+ users.*/\1/p' file
92 days, 5:00
4:24
11 min
3 min
我假设这也能处理好几年!
uptime | awk '{print $3}' | tr -d ,
鉴于@sudo_O 的正常运行时间输出示例(谢谢!):
$ cat file
12:46:18 up 92 days, 5:00, 2 users, load average: 0.00, 0.01, 0.05
12:47:30 up 4:24, 7 users, load average: 0.34, 0.12, 0.07
$ awk -F'[ ,]+' '{print $3 (/days/?" "$4" "$5:"")}' file
92 days 5:00
4:24
$ sed 's/.*up *\(.*\), *[0-9]* users.*/\1/' file
92 days, 5:00
4:24
使用sed
:
uptime | awk '{print $3}' | sed '$ s/,$//'