我有一个如下文件来进行日期和数字验证。文件:
006063416.01|USD|1| |00.00000|00.00000|O| |20100802|20160119| |D|+0000006063416|0000000000| |060.634164000|
06063416.001|AUD|M| |00.00000|00.00000|O| |2015991130|20160319| |D|+0000006063416|0000000000| |006a063416096|
06063416.002|HKD|M| |00.00000|00.00000|O| |20151130|20168919| |D|+0000006063416|0000000000| |006063416075|
脚本:
#!/bin/ksh
set -x
validate() {
echo "Performing file validations ..."
file=/var/applications/scripts/bin/CLIMAMT_SG
CURR_DTTM=`date +%Y%m%d.%H%M%S`
output=/var/applications/scripts/bin/output_CLIMAMT_SG.${CURR_DTTM}
awk -F\| '$16 !~ /^[0-9]+$/ {print "Line:"NR" Field:16 "$16" is not Numeric"}(date "+%Y%m%d" -d "$10")+0 != "$10"{print "Line:"NR" Field:10 "$10" is not in date format";next}' $file > $output
echo "Validation Complete"}
validate
输出:
Line:1 Field:16 060.634164000 is not Numeric
Line:1 Field:10 20160119 is not in date format
Line:2 Field:16 006a063416096 is not Numeric
Line:2 Field:10 20160319 is not in date format
Line:3 Field:10 20168919 is not in date format
问题甚至 20160319 也被报告为不正确
答案1
这行:
(date "+%Y%m%d" -d "$10")+0 != "$10"{print "Line:"NR" Field:10 "$10" is not in date format";next}
做不是调用外部命令date
。 awk 会这样解析:
- 运算
-
符的优先级高于字符串连接,因此首先我们取字符串“%Y%m%d”并减去变量d
,得到值0
- 现在我们获取变量的值
date
(为空)并将 0 和字符串“$10”连接起来(不是第10个字段的值) - 这会产生字符串
"0$10"
- 然后我们向该字符串添加零,结果为零
- 并将其与第 10 个字段的值进行比较。
0
仅当您在第 10 字段中时才会匹配。
GNU awk 有一些时间函数,所以你可以做类似的事情(未经测试)
function validate_date(datestr, timespec) {
timespec = substr(datestr,1,4) " " substr(datestr,5,2) " " substr(datestr,7,2) " 0 0 0")
return mktime(timespec)
}
{
if (validate_date($10) == -1) {
print $10 " is an invalid date"
}
}
答案2
这部分我错了,格伦答对了,但不管怎样不(date "+%Y%m%d" -d "$10")+0
在 awk 中,当变量date
和未设置时,减去数值为零的d
两个字符串和字段 10(的值),在这种情况下可能会产生值 -20161499。+%Y%m%d
20161499
date
根据需要运行。
要从 awk 运行命令并获取其输出,请使用管道形式getline
(查看您的系统或在线信息)但你不能完全适应某种情况,所以让它成为你行动的一部分:
{ cmd = "date +%Y%m%d -d " $10; cmd | getline checktime; close (cmd);
if( checktime != $10 ) { print "invalid time" $10; next } }
或者,如果您有 GNU awk
(如果您有 GNU,date
您可能会这样做),您可以使用内置函数mktime
和strftime
(确实适合中等复杂的情况)
strftime("%Y%m%d", mktime(substr($10,1,4)" "substr($10,5,2)" "substr($10,7,2)" 00 00 00")) == $10