关于shell:如何在awk脚本中进行日期/时间计算和格式化?

How to do date/time calculation and formatting in an awk script?

我有一个文件test.txt,有多个记录,如下所示。

1
2
100,200,300,08-May-2012 11:24:25
100,400,300,25-May-2012 09:24:25

现在,我想使用以下"格式"输出数据:

1
$1,$2,$3,$4,$4+30days,$4+60days,$4+90days

我怎样才能用awk来做到这一点?


script.awk文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function map_month(m)
{
    if (m ~ /[jJ][aA][nN]/) return 1;
    if (m ~ /[fF][eE][bB]/) return 2;
    if (m ~ /[mM][aA][rR]/) return 3;
    if (m ~ /[aA][pP][rR]/) return 4;
    if (m ~ /[mM][aA][yY]/) return 5;
    if (m ~ /[jJ][uU][nN]/) return 6;
    if (m ~ /[jJ][uU][lL]/) return 7;
    if (m ~ /[aA][uU][gG]/) return 8;
    if (m ~ /[sS][eE][pP]/) return 9;
    if (m ~ /[oO][cC][tT]/) return 10;
    if (m ~ /[nN][oO][vV]/) return 11;
    if (m ~ /[dD][eE][cC]/) return 12;
    return 0;
}
function cvt_timestamp(str,     t, a)
{
    split(str, a, /[- :]/)
    a[2] = map_month(a[2])
    #print a[3]"" a[2]"" a[1]"" a[4]"" a[5]"" a[6]
    t = mktime(a[3]"" a[2]"" a[1]"" a[4]"" a[5]"" a[6])
    #print t
    return t
}
function fmt_timestamp(t)
{
    return strftime("%d-%b-%Y %H:%M:%S", t)
}
BEGIN { FS = OFS ="," }
{
    tm = cvt_timestamp($4);
    t0 = fmt_timestamp(tm +  0 * 86400)
    t1 = fmt_timestamp(tm + 30 * 86400)
    t2 = fmt_timestamp(tm + 60 * 86400)
    t3 = fmt_timestamp(tm + 90 * 86400)
    print $1, $2, $3, t0, t1, t2, t3
}

也许有更好的方法来做数字映射的月份缩写;有了它。使用awk中的函数与使用函数的任何其他语言中的函数一样有价值。

示例data文件

1
2
3
4
100,200,300,08-May-2012 11:24:25
100,400,300,25-May-2012 09:24:25
100,400,300,15-Sep-2012 09:24:25
100,400,300,29-Feb-2012 09:24:25

号示例输出

1
2
3
4
5
6
$ gawk -f script.awk data
100,200,300,08-May-2012 11:24:25,07-Jun-2012 11:24:25,07-Jul-2012 11:24:25,06-Aug-2012 11:24:25
100,400,300,25-May-2012 09:24:25,24-Jun-2012 09:24:25,24-Jul-2012 09:24:25,23-Aug-2012 09:24:25
100,400,300,15-Sep-2012 09:24:25,15-Oct-2012 09:24:25,14-Nov-2012 08:24:25,14-Dec-2012 08:24:25
100,400,300,29-Feb-2012 09:24:25,30-Mar-2012 10:24:25,29-Apr-2012 10:24:25,29-May-2012 10:24:25
$

如果您决定要以不同的方式处理时区中的开关,这就是您的特权;您可以修复代码。