[Linux] Awk를 이용하여 텍스트/숫자 빅데이터 자료 처리 및 통계 계산

정보

  • 업무명     : Awk를 이용하여 텍스트/숫자 빅데이터 자료 처리 및 통계 계산

  • 작성자     : 이상호

  • 작성일     : 2020-07-15

  • 설   명      :

  • 수정이력 :

 

 내용

[개요]

  • 안녕하세요? 기상 연구 및 웹 개발을 담당하고 있는 해솔입니다.

  • 텍스트 형식의 숫자 데이터 처리 및 분석은 Awk + 쉘 스크립트가 유용합니다.

  • 특히 기상 자료와 같은 빅데이터엑셀이나 C 언어, Fortran 등으로 자료 처리한 경우 더욱 더 필요합니다.

  • 오늘 포스팅은 Awk를 이용하여 텍스트/숫자 빅데이터 자료 처리 및 통계 계산을 소개드리고자 합니다.

 

 

[특징]

  • 빅데이터 자료 처리를 이해하기 위해서 Awk이 요구되며 이 프로그램은 이러한 목적을 달성하기 위한 소프트웨어

 

[기능]

  • 빅데이터 자료 처리

  • 통계 계산

 

[활용 자료]

  • 파일명 : sample.txt

  • 자료 종류 : 날짜 및 시간에 따른 광합성 유효 복사 (Photosynthetic Active Radiation, PAR)

  • 시간 해상도 : 5분 간격

  • 열 정보 : 연도, 쥴리안 데이 (Julian Day), 시분, 센서 1, 센서 2, 센서 3

  • 쥴리안 데이의 경우 1월 1일에서 12월 31일을 365으로 설정

  • 시분은 1 또는 2 자리에서 의미 (예를 들어 605은 오전 6시 05분)

  • 센서 1의 경우 상단 및 센서 2, 3은 하향에서의 측정값을 의미하고 각각 센서의 전압 (mV)로 표현

  • 실질적인 물리적인 값 (mol/m2/sec)으로 변환하기 위해서 변환 계수를 고려

  • 각 열마다 쉼표로 구분

 

 

[자료 처리 방안 및 활용 분석 기법]

  • 없음

 

[사용법]

  • 작업 환경 구축

  • 소스 코드 작성 및 실행

  • 실행 결과 확인

 

[사용 OS]

  • Linux (CentOS v7.0)

  • VMware Workstation Pro v15.5

 

[사용 언어]

  • Shell Script (Bash)

 

 빅데이터 자료 처리

[명세]

  • 작업 환경

    • sample.txt : 입력 자료

    • RunShell.sh : 실행 프로그램

 

  • 센서 1-3에서 각 변환 계수 (293.73, 306.82, 290.84)를 통해 물리적 변수 환산

    • BEGIN { FS = "," }를 통해 각 행의 열을 , (쉼표)로 구분하여 전압 출력 (mV x 변환 계수)

    • 일반적으로 FS는 공백 또는 탭으로 기본값 지정   

#!/bin/bash

cat sample.txt |\
   awk 'BEGIN { FS = "," } { 
      print $1, $2, $3, $4*293.73, $5*306.82, $6*290.84 
   }'

 

 

  • 연속적인 시간 스케일을 위해 시분을 하루의 분으로 표시

    • 즉 시분의 경우 불연속 구간 존재하기 때문에

    • 예를 들어 6:59분 이후로 6:60가 아니라 7:00으로 불연속 발생

#!/bin/bash

cat sample.txt |\
   awk 'BEGIN { FS = "," } { 
      min = $3 % 100; 
      hour = ($3 - min) / 100; 
      print $1, $2, min + hour*60, $4*293.73, $5*306.82, $6*290.84
   }'

 

 

  • 하루에 대한 시계열을 위해 1일 단위로 스케일 조정

#!/bin/bash

cat sample.txt |\
   awk 'BEGIN { FS = "," } {
      min = $3 % 100; 
      hour = ($3 - min) / 100; 
      print $1, $2 + (min + hour * 60) / 1440, $4*293.73, $5*306.82, $6*290.84
   }'

 

 

  • 표준 출력 (>)을 통해 conv.txt 저장 

#!/bin/bash

cat sample.txt |\
   awk 'BEGIN { FS = "," } {
      min = $3 % 100; 
      hour = ($3 - min) / 100; 
      print $1, $2 + (min + hour * 60) / 1440, $4*293.73, $5*306.82, $6*290.84
   }' > conv.txt

 

 

  • gnuplot를 통해 센서에 따라 시간별 물리값 시각화

#!/bin/bash

gnuplot << EOF
   set terminal  postscript size 12, 10 color enhanced font "Times-New-Roman, 24" background rgb "white"
   set output "Image_01.png"
   set title "PAR"
   set yrange [0:2500]
   set ylabel "PAR [umol/m2/sec]"
   set xlabel "DAY (2005)"
   plot "conv.txt" u 2:3 title "above canopy" w l, "conv.txt" u 2:4 title "under canopy" w l, "conv.txt" u 2:5 title "under canopy" w l
EOF
 
mogrify -rotate 90 -matte -background none Image_01.png
display Image_01.png

 

 

  • 이와 같은 쉘 스크립트를 사용하면 다수 장점

    • 1차 데이터에서 최종 결과 (그래프)까지의 처리 과정을 완벽하게 기록할 수 있고 필요 시 손쉽게 재현 가능

    • 동일한 형식의 자료에 대해 반복 수행

    • 자료 처리의 일부를 변경하고 다시 시작하는 것도 쉬움

      • 예를 들어 센서의 출력을 실제 값으로 변환 계수를 변경할 경우

    • 자료 처리의 노하우를 공개하거나 다른 연구자들과 공유하는 것이 용이

 

 통계 계산

[명세]

  • 센서 1의 출력에 대해 일별 합계 (단위: mol/day) 수행

#!/bin/bash

cat conv.txt |\
   awk 'BEGIN { D = 170; a = 0; t = 170.0 } 
      D + 1 <= $2 {
         print D, a; a = 0; D++
         } 
      { 
         a = a + $3 * ($2 - t) * 60 * 60 * 24 / 1000000; 
         t = $2
      }'

 

 

  • 센서 1를 이용하여 센서 2/3에 대한 투과율 계산

#!/bin/bash

cat conv.txt | awk '{ print $1, $2, $4/$3, $5/$3 }'

 

 

  • 센서 1를 이용하여 센서 2/3에 대한 투과율 계산

    • 센서 1에서 0일 경우 오류 발생

#!/bin/bash

cat conv.txt | awk '{ print $1, $2, $4/$3, $5/$3 }'

 

 

  • 센서 1를 이용하여 센서 2/3에 대한 투과율 계산

    • 센서 1에서 0일 경우 오류 발생

#!/bin/bash

cat conv.txt | awk '{ print $1, $2, $4/$3, $5/$3 }'

 

 

  • 센서 1를 이용하여 센서 2/3에 대한 투과율 계산

    • 계산하기 앞서 조건문 (센서 1 > 0) 수행 

#!/bin/bash

cat conv.txt | awk '$3 > 0 { print $1, $2, $4/$3, $5/$3 }'

 

 

  • 표준 출력 (>)을 통해 trans.txt 저장

#!/bin/bash

cat conv.txt | awk '$3 > 0 { print $1, $2, $4/$3, $5/$3 }' > trans.txt

 

 

  • 센서 2/3에 대한 시간별 투과율 시각화

#!/bin/bash

gnuplot << EOF
   set terminal  postscript size 12, 10 color enhanced font "Times-New-Roman, 24" background rgb "white"
   set output "Image_02.png"
   set title "PAR Transmittance"
   set yrange [0:1]
   set ylabel "PAR Transmittance"
   set xlabel "DAY (2005)"
   plot "trans.txt" u 2:3 title "sensor 2" w l, "trans.txt" u 2:4 title "sensor 3" w l
EOF

mogrify -rotate 90 -matte -background none Image_02.png
display Image_02.png

 

 

[전체]

#!/bin/bash

cat sample.txt |\
   awk 'BEGIN { FS = "," } { 
      print $1, $2, $3, $4*293.73, $5*306.82, $6*290.84 
   }'

cat sample.txt |\
   awk 'BEGIN { FS = "," } { 
      min = $3 % 100; 
      hour = ($3 - min) / 100; 
      print $1, $2, min + hour*60, $4*293.73, $5*306.82, $6*290.84
   }'

cat sample.txt |\
   awk 'BEGIN { FS = "," } {
      min = $3 % 100; 
      hour = ($3 - min) / 100; 
      print $1, $2 + (min + hour * 60) / 1440, $4*293.73, $5*306.82, $6*290.84
   }'

cat sample.txt |\
   awk 'BEGIN { FS = "," } {
      min = $3 % 100; 
      hour = ($3 - min) / 100; 
      print $1, $2 + (min + hour * 60) / 1440, $4*293.73, $5*306.82, $6*290.84
   }' > conv.txt

gnuplot << EOF
   set terminal  postscript size 12, 10 color enhanced font "Times-New-Roman, 24" background rgb "white"
   set output "Image_01.png"
   set title "PAR"
   set yrange [0:2500]
   set ylabel "PAR [umol/m2/sec]"
   set xlabel "DAY (2005)"
   plot "conv.txt" u 2:3 title "above canopy" w l, "conv.txt" u 2:4 title "under canopy" w l, "conv.txt" u 2:5 title "under canopy" w l
EOF
 
mogrify -rotate 90 -matte -background none Image_01.png
display Image_01.png

cat conv.txt |\
   awk 'BEGIN { D = 170; a = 0; t = 170.0 } 
      D + 1 <= $2 {
         print D, a; a = 0; D++
         } 
      { 
         a = a + $3 * ($2 - t) * 60 * 60 * 24 / 1000000; 
         t = $2
      }'

cat conv.txt | awk '{ print $1, $2, $4/$3, $5/$3 }'

cat conv.txt | awk '$3 > 0 { print $1, $2, $4/$3, $5/$3 }'

cat conv.txt | awk '$3 > 0 { print $1, $2, $4/$3, $5/$3 }' > trans.txt

gnuplot << EOF
   set terminal  postscript size 12, 10 color enhanced font "Times-New-Roman, 24" background rgb "white"
   set output "Image_02.png"
   set title "PAR Transmittance"
   set yrange [0:1]
   set ylabel "PAR Transmittance"
   set xlabel "DAY (2005)"
   plot "trans.txt" u 2:3 title "sensor 2" w l, "trans.txt" u 2:4 title "sensor 3" w l
EOF

mogrify -rotate 90 -matte -background none Image_02.png
display Image_02.png

 

 참고 문헌

[논문]

  • 없음

[보고서]

  • 없음

[URL]

  • 없음

 

 문의사항

[기상학/프로그래밍 언어]

  • sangho.lee.1990@gmail.com

[해양학/천문학/빅데이터]

  • saimang0804@gmail.com

 

 

 

 

 

 

 

 

 

 

본 블로그는 파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음