How to convert a date string to timestamp in gawk?

主宰稳场 提交于 2019-12-08 05:17:15

问题


I am scanning through a log file formatted like this:

76.69.120.244 - - [09/Jun/2015:17:13:18 -0700] "GET /file.jpg HTTP/1.1" 200 22977 "http://example.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36" "16543" "ewr1" "0.002" "CA" "Bell Canada" "2"
76.69.120.244 - - [09/Jun/2015:17:13:19 -0700] "GET /differentfile.bin HTTP/1.1" 206 453684 "http://example.com/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36" "16543" "ewr1" "1.067" "CA" "Bell Canada" "2"

Inside gawk, I'm getting that request time using:

requesttime=$4;

What's the best way for me to parse that into a UTC/GMT based time, preferably an epoch timestamp?

I can at least always guarantee that it will be in -0700 if that helps; perhaps some kind of ugly string transformation to add those 7 hours on to it?


回答1:


This will do the main part of converting your date+time (it ignores the -0700) to a number of secs since the epoch for your current locale:

$ cat tst.awk
BEGIN { FS="[][]" }
{
    split($2,a,"[/: ]")
    match("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])
    a[2] = sprintf("%02d",(RSTART+2)/3)
    secs = mktime(a[3]" "a[2]" "a[1]" "a[4]" "a[5]" "a[6])
    print $2, "->", secs
}

$ awk -f tst.awk file
09/Jun/2015:17:13:18 -0700 -> 1433887998
09/Jun/2015:17:13:19 -0700 -> 1433887999

and then you can either do some math on the secs or set the TZ variable appropriately before calling awk, e.g. (idk if this is the right TZ to use for your data/locale or not):

$ TZ=UTC awk -f tst.awk file
09/Jun/2015:17:13:18 -0700 -> 1433869998
09/Jun/2015:17:13:19 -0700 -> 1433869999

You can get your current locales time zone offset with strftime("%z"):

$ awk 'BEGIN{print strftime("%z")}'
-0500

so your final solution that includes the offset calculation might be or include (check the math as you didn't show what your expected output is and I might be misinterpreting what your data means to you!):

$ cat tst.awk
BEGIN {
    FS="[][]"
    locOffset = strftime("%z")
}
{
    split($2,a,"[/: ]")
    match("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])
    a[2] = sprintf("%02d",(RSTART+2)/3)
    secs = mktime(a[3]" "a[2]" "a[1]" "a[4]" "a[5]" "a[6])
    secs = secs + (locOffset - a[7]) * 60 * 60
    print $2, "->", secs
}

$ awk -f tst.awk file
09/Jun/2015:17:13:18 -0700 -> 1434607998
09/Jun/2015:17:13:19 -0700 -> 1434607999

or if you like brevity and puzzles ( ;-) ):

$ cat tst.awk
BEGIN { FS="[][]" }
{
    split($2,a,"[/: ]")
    print $2, "->", mktime(a[3]" "(match("JanFebMarAprMayJunJulAugSepOctNovDec",a[2])+2)/3" "a[1]" "a[4]" "a[5]" "a[6]) + (strftime("%z") - a[7])*60*60
}

$ awk -f tst.awk file
09/Jun/2015:17:13:18 -0700 -> 1434607998
09/Jun/2015:17:13:19 -0700 -> 1434607999



回答2:


Here is another solution which uses the system call in gawk. Hope it would be helpful.

$ awk 'BEGIN{FS="[][]"}{system("date \"+%s\" -d \""gensub("/", " ", "G", gensub(":", " ", "1", $2))"\"")}' file 
1433895198
1433895199


来源:https://stackoverflow.com/questions/31054060/how-to-convert-a-date-string-to-timestamp-in-gawk

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!