与时间戳相比,我可以获得结果吗?

时间:2014-10-16 14:10:25

标签: linux bash grep text-files

我有一个制表符分隔的文本文件,其中包含三个字段:TIMESTAMPHOSTSTATUS。我需要找到一个主机是否在不到一个小时前被列为停机。到目前为止,我有这个例子:

grep "Down" thetextfile.txt | grep "thehostname"

这给了我一个主机在日志中关闭的所有时间的列表。凉。现在我想我只需要了解最新的TIMESTAMP是否不到一个小时。我是Linux和Bash脚本的新手,但在我对实际数据库的其他工作中,这将是一个相对简单的查询。

有什么想法吗?或者有更好的方法吗?

以下是日志文件的示例:

TIMESTAMP       HOST    STATUS
Wed Oct 8 12:16:23 EDT 2014      aserver       Alive
Wed Oct 8 12:16:23 EDT 2014      anotherserver     Down

谢谢!

2 个答案:

答案 0 :(得分:2)

您可以使用此BASH脚本:

#!/bin/bash

# current date-time in seconds (epoch) value
now=$(date '+%s')

while read -r p; do
    # ignore 1st row with headers
    [[ "$p" == *TIMESTAMP* ]] && continue

    # read 3 values in 3 variables t h s
    IFS=$'\t' && read t h s <<< "$p"

    # convert date string to epoch value
    ts=$(date -d "$t" '+%s')

    # if date from file is less than 1 hour ago and status is Down then print host name
    [[ "$s" == "Down" ]] && (( (now-ts) < 3600 )) && echo "$h"
done < file

答案 1 :(得分:2)

我使用GNU awk:

gawk -v status=Down -v host=anotherserver '
    BEGIN {
        mo["Jan"]=1; mo["May"]=5; mo["Sep"]=9
        mo["Feb"]=2; mo["Jun"]=6; mo["Oct"]=10
        mo["Mar"]=3; mo["Jul"]=7; mo["Nov"]=11
        mo["Apr"]=4; mo["Aug"]=8; mo["Dec"]=12
    }
    function elapsed(month, day, time, year) {
        gsub(/:/, " ", time)
        return systime() - mktime(sprintf("%d %02d %02d %s", year, mo[month], day, time));
    }
    $NF == status && $(NF-1) == host && elapsed($2,$3,$4,$6) < 3600
' <<DATA
TIMESTAMP       HOST    STATUS
Wed Oct 8 12:16:23 EDT 2014      aserver       Alive
Wed Oct 8 12:16:23 EDT 2014      anotherserver     Down
Wed Oct 16 10:16:23 EDT 2014      aserver       Alive
Wed Oct 16 10:16:23 EDT 2014      anotherserver     Down
Wed Oct 16 10:16:23 EDT 2014      aserver       Down
Wed Oct 16 10:16:23 EDT 2014      anotherserver     Up
DATA
Wed Oct 16 10:16:23 EDT 2014      anotherserver     Down

当前日期是2014年10月16日星期四10:53:45 EDT 2014