如何在Linux中解析经过的时间(以秒为单位)

如何在Linux中解析经过的时间(以秒为单位)

我想解析经过的时间(以秒为单位)。时间格式如下:

1) 3 day 18h
2) 3 day
3) 3h 15min
4) 3h 
5) 15min 10sec
6) 15min 
7) 10sec

我从中获取价值systemctl status cassandra | awk '/(Active: active)/{print $9, $10,$11}'现在将其值存储在变量 A 中,例如

A=$(systemctl status cassandra | awk '/(Active: active)/{print $9, $10,$11}'

现在 A 输入了 as3 day 18h3 day等。更多示例-

A=3 day 18h or 3 day or 3h 15min or 3h or 15min 10sec or 15min or 10sec

现在采用不同的 A 值,并在几秒钟内进行解析。

答案1

您可以使用date命令来解析这些值,如下所示:

        adjusted_val="$(printf '%s' "$val" | sed 's/h/hour/')"
        result="$(date -d "$(date -d @0) + $adjusted_val" +%s)"

奇怪的是,date它不识别h(甚至不识别hr)作为“hour”的缩写,因此,第一步,我们将h字符串替换为hour。然后我们通过将@0(Unix time 0) 扩展为字符串来找到“纪元时间”——Unix 日期/时间计数的日期/时间。 (众所周知,记录为“Jan 1, 1970 00:00:00 GMT”,因此我们可以硬编码该值。)然后我们添加您的字符串:例如,(Jan 1) + 3 day( s) 是 1 月 4 日。然后我们将该+%s日期/时间显示为 Unix 数字日期/时间,即纪元之后的秒数。这对应于字符串的间隔(增量)值。

如果您想一次执行多个值,您可以通过仅计算一次纪元来优化它:

#!/bin/sh
epoch="$(date -d @0)"
for val
do
        adjusted_val="$(printf '%s' "$val" | sed 's/h/hour/')"
        if result="$(date -d "$epoch + $adjusted_val" +%s)"
        then
                printf '%-12s -> %6d\n' "$val" "$result"
        else
                printf '%-12s <- error\n' "$val"
        fi
done

结果:

$ ./myscript '3 day 18h' '3 day' '3h 15min' '3h' '15min 10sec' '15min ' \
                                                       '10sec' 'a moment' '3 weeks'
3 day 18h    -> 324000
3 day        -> 259200
3h 15min     ->  11700
3h           ->  10800
15min 10sec  ->    910
15min        ->    900
10sec        ->     10
date: invalid date ‘Wed, Dec 31, 1969  7:00:00 PM + a moment’
a moment     <- error
3 weeks      -> 1814400

请注意,date -d可以处理“月”一词。如果您有可能获得包含该单词的值,则需要使命令sed更智能,这样它就不会更改“month”中的“h”。

但是,如果你确实想处理几个月,你应该认真思考“一个月”是什么。例如,我在 2020 年 4 月 12 日写这篇文章。一个月后就是 5 月 12 日——还有 30 天。一个月前是 3 月 12 日,也就是 31 天前。两个月前是2月12日,也就是60(31+29)天前。但是等等,在非闰年中,2 月只有 28 天,因此 2 月 12 日和 4 月 12 日仅相隔 59 天。还有更多:(至少)在美国,2月12日是标准时间,3月12日是夏令时,所以(在非闰年)2月12日中午和3月12日中午只有27天,相隔23小时。情况很复杂。

答案2

我们不能依赖于天和小时参数,因为 7 天后我们将获得周参数,30 天后我们将获得月份参数。

所以最好用Service start time来计算。

#!/bin/bash
SERVICE=cassandra
SERVICE_START_TIME=`systemctl status $SERVICE | awk '/Active: active/{print $6" "$7}'`
SERVICE_UP_TIME=$(($(date +%s) - $(date -d "$SERVICE_START_TIME" +%s)))
echo "$SERVICE uptime : $SERVICE_UP_TIME"

您可以尝试以下一行代码,但我建议使用上面的代码以获得准确的结果。

systemctl status cassandra | awk -F ';' '/Active: active/{print $2}' |  sed -e 's/s ago/ 1/; s/s//g; s/min/ 60/; s/h ago/ 3600/; s/day/86400/; s/week/606800/; s/month/2592000/; s/ago//' | awk '{a=$1*$2;b=$3*$4;c=$a+$b;print a" sec"}'

相关内容