ajuda a corrigir declaração awk

0

Eu tenho um arquivo como abaixo para fazer a validação de data e número. Arquivo :

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|  

Script :

#!/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   

saída :

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  

problema é que até 20160319 é reportado como incorreto

    
por user212652 01.02.2017 / 18:45

2 respostas

4

Esta linha:

(date "+%Y%m%d" -d "$10")+0 != "$10"{print "Line:"NR" Field:10 "$10" is not in date format";next}

não chama o comando date externo. O awk analisa isso assim:

  1. o operador - tem precedência mais alta que a concatenação de strings, então primeiro pegamos a string "% Y% m% d" e subtraímos a variável d , resultando no valor 0
  2. agora pegamos o valor da variável date (que está vazia) e concatenamos 0 e a string "$ 10" ( não o valor do décimo campo)
  3. isso resulta na string "0$10"
  4. então adicionamos zero a essa string, resultando no valor zero
  5. e compare isso com o valor do décimo campo.

Isso só será igual se você tiver 0 no décimo campo.

GNU awk tem algumas funções de tempo, então você pode fazer algo como (não testado)

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"
    }
}
    
por 01.02.2017 / 20:17
2

(date "+%Y%m%d" -d "$10")+0 no awk quando as variáveis date e d não estão definidas subtrai as duas cadeias +%Y%m%d que tem um valor numérico de zero e (o valor de) campo 10 que, nesse caso, pode ser 20161499 produzindo assim o valor -20161499. Eu entendi errado e glenn acertou, mas de qualquer forma ele não executa date como desejado.

Para executar um comando a partir do awk e obter sua saída, use o formulário de canal de getline (veja informações no seu sistema ou on-line) , mas você não pode ajustá-lo totalmente em uma condição para torná-lo parte de sua ação:

{ cmd = "date +%Y%m%d -d " $10; cmd | getline checktime; close (cmd);
  if( checktime != $10 ) { print "invalid time" $10; next } }

Como alternativa, se você tiver o GNU awk (e se você tiver o GNU date provavelmente), você pode usar o funções incorporadas mktime e strftime (que se encaixam em uma condição moderadamente complicada)

 strftime("%Y%m%d", mktime(substr($10,1,4)" "substr($10,5,2)" "substr($10,7,2)" 00 00 00")) == $10
    
por 01.02.2017 / 20:15

Tags