AWK是否可以读取时间字段并将其用于排序?

时间:2014-02-26 21:13:50

标签: linux bash awk gawk nawk

我有两个文件,我需要根据时间列对行进行排序和合并:

档案A:

"2014-02-26 16:03:04"   "Login Success|isNoSession=false"   id=csr,ou=user,dc=openam,dc=forgerock,dc=org    7efb2f0e035a0e3d01  10.17.174.30    INFO    dc=openam,dc=forgerock,dc=org   "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org" AUTHENTICATION-100  DataStore   "Not Available" 10.17.174.30

档案B:

"2014-02-26 16:02:27"   "Login Failed"  dennis  "Not Available" 10.17.174.30    INFO    dc=openam,dc=forgerock,dc=org   "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org" AUTHENTICATION-200  DataStore   "Not Available" 10.17.174.30    
"2014-02-26 16:02:37"   "Login Failed"  purva   "Not Available" 10.17.174.30    INFO    dc=openam,dc=forgerock,dc=org   "cn=dsameuser,ou=DSAME Users,dc=openam,dc=forgerock,dc=org" AUTHENTICATION-200  DataStore   "Not Available" 10.17.174.30

我需要合并文件(非常标准)但我必须根据第1列中的时间将行插入到最终文件中。我还有其他几个要修改的项目,但我很确定我能算出来那个。基于时间列的排序让我感到难过。

所以在这种情况下,我会得到一个文件,最后是文件A中的行。

其他细节。

只是为了刷新自己,我正在解析第一个文件。以下是我到目前为止的情况:

#!/bin/awk -f
BEGIN {
    FS="\t";
}
{
    # if we have more than 12 fields for the current row, proceed
    if ( NF > 12 )
    {
        # start looking for the user name
        n = split( $3, var1, ",");
        if (n > 4)
        {
            n2 = split (var1[1], var2, "=");
            if (n2 >= 2)
            {
                # Ignore any line where we do not have "id=xxxxx,..."
                if (var2[1] == "id")
                {
                    print $1, "N/A", "N/A", $12, $5, $5, var2[2]
                }
            }
        }
    }
}
END {
    print "Total Number of records=" NR
}

我可能需要将其移动到一个函数中以使其更容易,因为我将同时处理两个文件。

2 个答案:

答案 0 :(得分:1)

基于linuxbash标记,您可以连接这两个文件,按第一个字段对它们进行排序,然后将awk命令应用于结果:

cat fileA fileB | sort -t$'\t' -s -k1,1 | awk -f script.awk

答案 1 :(得分:1)

一些额外的工作,但如果你想在awk(GNU awk)中完成,那么你将不得不使用mktimestrftime函数。

以下是提示:

awk '{
    # Split the time field so that you have a pattern of YYYY MM DD HH MM SS
    split($0, t, /[-: ]/); 
    patt = t[1] FS t[2] FS t[3] FS t[4] FS t[5] FS t[6];  
    # Store your variable in array
    time[mktime(d)]++
}
END {
    # Sort the array so that you get sorted time
    x = asorti(time, s_time)
    # Iterate over your new sorted array and print it in desired format
    for(i=1; i<=x; i++) {
        print strftime("%Y-%m-%d %T",s_time[i])
    }
}' file

$ cat file
2014-02-26 16:03:04
2017-02-26 16:02:27
2012-02-26 16:02:37

$ awk '{
    split($0, t, /[-: ]/); 
    patt = t[1] FS t[2] FS t[3] FS t[4] FS t[5] FS t[6];   
    time[mktime(d)]++
}
END {
    x = asorti(time, s_time)
    for(i=1; i<=x; i++) {
        print strftime("%Y-%m-%d %T",s_time[i])
    }
}' file
2012-02-26 16:02:37
2014-02-26 16:03:04
2017-02-26 16:02:27