纠正 awk 语句

纠正 awk 语句

我有一个如下文件来进行日期和数字验证。文件

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 会这样解析:

  1. 运算-符的优先级高于字符串连接,因此首先我们取字符串“%Y%m%d”并减去变量d,得到值0
  2. 现在我们获取变量的值date(为空)并将 0 和字符串“$10”连接起来(不是第10个字段的值)
  3. 这会产生字符串"0$10"
  4. 然后我们向该字符串添加零,结果为零
  5. 并将其与第 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%d20161499这部分我错了,格伦答对了,但不管怎样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您可能会这样做),您可以使用内置函数mktimestrftime (确实适合中等复杂的情况)

 strftime("%Y%m%d", mktime(substr($10,1,4)" "substr($10,5,2)" "substr($10,7,2)" 00 00 00")) == $10

相关内容