2014-11-05 96 views
1

我有一个awk脚本,我需要验证大量包含日期的行。Awk日期验证

我目前正在使用基于正则表达式的解决方案来进行基本验证(没有测试闰年或)或调用UNIX日期命令来更准确地验证它。 date命令运行良好,但在性能方面调用系统命令相当昂贵。

我希望这里的某个人能够提出一个既准确又快速的解决方案。

这里是我的数据的一个例子

20140804024614 
20140803190020 
20140803163320 
20140803083222 
20140803170321 
20140803234044 
20140804011857 
20140803204008 
20140803160026 
20140803140120 

感谢。

+0

你在使用GNU awk吗?如果是这样,请https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html – 2014-11-05 16:05:46

+0

请显示您的尝试,也许您正在使用对系统调用的过度复杂的调用。 – fedorqui 2014-11-05 16:11:36

+0

您是如何将这种格式与“UNIX日期”配合使用的? – hek2mgl 2014-11-05 16:13:53

回答

2

给出了一大堆对你的输入文件的假设,这个可能是你所需要的仅仅使用GNU AWK时间功能和gensub()打印有效日期+时间:

awk 'strftime("%Y%m%d%H%M%S",mktime(gensub(/(.{4})(..)(..)(..)(..)/,"\\1 \\2 \\3 \\4 \\5 ",""))) == $0' file 

它只会以来的划时代日期工作。

如果您需要打印某种“有效/无效”消息的每个日期/时间:

$ cat file 
20140230035900 
20140804024614 
$ 
$ awk '{print (strftime("%Y%m%d%H%M%S",mktime(gensub(/(.{4})(..)(..)(..)(..)/,"\\1 \\2 \\3 \\4 \\5 ",""))) == $0 ? "" : "in") "valid:", $0}' file 
invalid: 20140230035900 
valid: 20140804024614 

上述工程的日期+时间转换为秒从新纪元,然后将那些秒到原始格式的日期+时间,如果结果与您开始的结果相同,则原始日期有效。

+0

嗨,这看起来像一个非常有用的解决方案。但是,由于包含2月30日的“20140230035900”这样的日期被标记为有效,因此似乎不起作用。 – Soucrit 2014-11-05 18:57:26

+0

仅供参考,输入文件包含许多列。日期字段实际上分成两列,其他任何一方都有效。 – Soucrit 2014-11-05 19:10:59

+1

谢谢。编辑后的版本完美运行。我注意到下次会添加错误的数据。 – Soucrit 2014-11-05 19:37:50

1

检查:

checkFormat() 
{ 
dateV="${1}" 

echo "${dateV}"|gawk '{ 
    if (match($0,/^((?:19|20)[0-9][0-9])(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])([01][0-9]|2[0-4])$/,a)) { 
     year=a[1]+0 
     mon=a[3]+0 
     day=a[4]+0 
     hour=a[5]+0 
     } 
    else { 
     print "KO: "$0 
     exit 
    } 

    if (day == 31 && (mon == 4 || mon == 6 || mon == 9 || mon == 11)) 
     print "KO: "$0 # 30 days months 
    else if (day >= 30 && mon == 2) 
     print "KO: "$0 # Febrary never 30 o 31 
    else if (mon == 2 && day == 29 && ! ( year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) 
     print "KO: "$0 # Febrary 29 leap year 
    else 
     print "Correct date !:" $0 
    }' 

} 


checkFormat 2014080417 
checkFormat 20140803190035 

用法:

$ ./checker.sh 
Correct date !:2014080417 
KO: 20140803190035 

注:MINUTESSECONDS将是你的任务:)

检查也:http://nixtip.wordpress.com/2011/11/28/an-awk-date-format-validator/