올바른 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. 그런 다음 해당 문자열에 0을 추가하면 결과는 0이 됩니다.
  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")+0awk에서 변수 date및 가 설정되지 않은 경우 숫자 값이 0인 두 문자열과 필드 10(값)을 빼면 d이 경우 -20161499 값이 생성될 수 있습니다.+%Y%m%d20161499 이 부분은 제가 틀렸고 Glenn이 옳았습니다. 하지만 어쨌든아니요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

관련 정보