在 BASH 中转换飞行日期时间

在 BASH 中转换飞行日期时间

我有一个包含以下输入的文件

Nov 29 15:15 ,alert_logevent
Nov 29 15:15 ,alert_webhook
Nov 29 15:15 ,appsbrowser
Oct 20 2017 ,ClearPassOnSplunk_2
Oct 10 2017 ,Dnslookup
Oct 12 2017 ,domainCategories

我想将日期时间转换为 YYYYMMDDHHMMSS 而不使用循环之类的东西

 cat SOMEFILE_WITH_DATE_AND_DATE | awk '{print "date -d \""$1, $2, $3"\"" " +" "%Y%m%d%H%M%S" , $4 }'

我希望输出看起来像这样

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20181129151500,appsbrowser

等等

我尝试了 awk 中的 system() 函数,但它不接受超过 1 个参数。

答案1

不确定您的预期输出与您的输入有何关系。我会建议:

$ perl -MPOSIX -MDate::Parse -pe 's{[^,]*}{
   strftime("%Y%m%d%H%M%S", localtime str2time($&))}e' <your-file
20171129151500,alert_logevent
20171129151500,alert_webhook
20171129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

要使用 GNUdate解析这些日期的能力,并避免date每行运行一次调用,您可以这样做(假设 shell 支持 ksh 样式的进程替换(如 ksh、bash 或 zsh)):

paste -d , <(<yourfile cut -d , -f1 | date -f- +%Y%m%d%H%M%S) \
           <(<yourfile cut -d , -f2-)

但请注意,它给出了:

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

虽然这是您所要求的,但听起来不太可能是您想要的,因为这些Nov 29 15:15听起来更有可能是 2017 年(去年)的时间戳,而不是未来的时间戳。

在这里,这些日期看起来像是ls -lPOSIX 语言环境中报告的。如此便携,您可以适应该功能来自另一个问答将其转换为更有用的格式。或者更好的是,使用一种比ls -l首先在文件中存储文件日期更好的方法(例如 GNUfind -printf或 GNUdate -r或 zsh stat,或 GNU/BSDstat或 ast ls --format...),您可以使用更有用、更精确和明确的格式。

答案2

如果零000000就可以,HHMMSS对于没有的条目时间数据,使用以下awk方法:

awk 'BEGIN{ FS = OFS = "," }
     { 
         cmd = "date -d\042" $1 "\042 +%Y%m%d%H%M%S";
         cmd | getline d; close(cmd);
         print d, $2
     }' file

输出:

20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

答案3

需要 GNU awk 来实现内置时间函数

gawk -F, -v OFS=, '
    BEGIN {
        # assumes english month names
        split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", m, ",")
        for (idx in m) months[m[idx]] = idx
        delete m
    }
    function date2timestamp(datestamp,    tmp,now,timestamp,year,hour,minute) {
        now = systime()
        split(datestamp, tmp, " ")
        if (tmp[3] ~ /:/) {
            year = strftime("%Y", now)
            hour = substr(tmp[3], 1, 2)
            minute = substr(tmp[3], 4, 2)
        }
        else {
            year = tmp[3]
            hour = minute = 0
        }
        timestamp = mktime(year " " months[tmp[1]] " " tmp[2] " " hour " " minute " 0")
        if (timestamp > now)
            timestamp = mktime((year-1) " " months[tmp[1]] " " tmp[2] " " hour " " minute " 0")
        return strftime("%Y%m%d%H%M00", timestamp)
    }
    {
        $1 = date2timestamp($1)
        print
    }
' file

输出

20171129151500,alert_logevent
20171129151500,alert_webhook
20171129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories

您的输入文件看起来像结果解析ls -l。您可能想跳过该文件并执行类似的操作

stat -c '%Y,%n' * | gawk -F, -v OFS=, '{$1 = strftime("%Y%m%d%H%M%S", $1)}1'

这并不安全(从处理带有换行符的文件名的意义上来说),但它会给您准确的文件 mtime。

相关内容