awk

IT/shell 위 댄스 2008. 2. 27. 18:59

[ 사용법 ]
 
  awk 은 설계자인 Aho, Weingrger, Kernighan의 첫글자로 명명되어진 패턴검색과
  처리 기능을 가진 인터프리티드 프로그래밍 언어로서 필터링, 치환, 간단한 리포팅 작업을 제어할수 있다.

1) "awk" 형식
     awk 프로그램은 세부분으로 구성되어 진다.
            BEGIN Section : 파일을 읽기전에 실행
            Pattern Statment Section : 파일의 각 레코드 라인을 읽어들일 때 마다 실행
            END Section : 파일을 다 읽어들인 뒤 실행

            BEGIN { statements ….}
                       /pattern expression / { statements  .... }
           END { statements… }

     여러개의 statement를 한 라인에 쓸때는 statement ; statement 의 형식으로 기술한다.

2) awk 명령어 실행 방법
     "awk" 프로그램을 명령어 상에서 입력하는 경우
     $ awk '{print $0 }' datafile ....

     단일인용문( ' ' ) 안에 프로그램을 기술한다. 데이터 파일을 정의하지 않으면 표준 입력으로부터 데이터를 입력 받는다.
     awk 프로그램을 파일로 작성하는 경우는
     $ awk -f awk-program-filename data-filenames
     ex)
        $ awk ' BEGIN { print "awk 프로그램 실행 연습입니다" } '
        $
        $ awk '{ print $1, $2 } ' data1
          100 200
          300 400
          500 600
       $
       $ cat ex01
        # This is sample file
        BEGIN {
            print "Hello, I'm Kim "
           exit }
      $
      $ awk -f ex01
         Hello, I'm Kim
      $


  3) 레코드
     레코드는 입력된 파일의 한 줄을 말한다. 라인 전체의 내용은 $0 변수명으로 사용되며,
     입력된 레코드 번호는 NR 이라는 변수로 표시 된다.

  4) 필드
     입력된 레코드에서 스페이스 또는 탭으로 구분되는 문자들을 말한다.
     각각의 필드는 $1,$2,$3,....$n 으로 필드위치에 따라 변수명으로 표기되며 현재 필드값은 NF 변수로 표시된다.

  5) 변수
     위치변수 는 필드 또는 레코드를 나타낸다.
     $0 : 현재 입력된 레코드를 나타내는 변수
     $1 : 현재 입력된 레코드의 첫 번째 필드를 나타내는 변수
     $n : 현재 입력된 레코드의 n번째 필드를 나타내는 변수
   
     재정의 변수는 입력된 레코드의 구성과 크기에 대한 정보를 제공한다.
       NR : 레코드 수
       NF : 필드 수
       FS : 필드 구분 문자
       RR : 레코드 구분 문자
       OFS : 출력 필드 구분 문자
       ORS : 출력 레코드 구분 문자
       FILENAME : 현재 입력된 파일 이름
      OFMT : 출력 인쇄 형식
     사용자 정의 변수는 프로그램의 어느 곳에서도 사용자가 정의하여 사용 할 수 있으며, 숫자 또는 문자열 값을 가진다.
     초기화 하지 않으면 자동적으로 null(0) 문자를 가진다.
     ex)
       $ cat data1
       100 200
       300 400
       500 600
       $ cat ex02
         BEGIN { OFS="------" }
         { print $1,$2 }
       $
       $ awk -f ex02 data1
        100------200
        300------400
        500------600
      $
      $ cat ex03
        { x = $1 + $2
           y = y + x }
        END { print y }
      $
      $ awk -f ex03 data1
       1600
      $

  6) 패턴 과 연산자
      패턴의 형식은 egrep과 유사한 형식을 가진다.
     정규식을 사용하여 패턴을 구성할 수 있으며 패턴은 "/ /" 형식으로 지정한다.
      "/ /,/ /" 형식을 사용하여 패턴으로 범위를 지정할 수 있다.
     ex)
       $ cat ex04
       $2 ~ /^[0-9]+$/ { print $2 }
        -> 두 번째 필드가 숫자로만 구성되어 있으면 두 번째 필드값을 출력
       $ awk -f ex04 data1
         200
         400
         600
       $
       $ cat ex05
       $0 ~ /[Ee]nd/ { print "end of", FILENAME }
       $
       -> 읽어 들인 레코드의 값이 End 또는 end이면 "end of data1" 과 같은 형식으로 출력
       $ cat ex05_1
          /Begin/,/End/ { total += $1 }
          END { print "Total = " total }

       연산자는 관계연산자, 패턴 연산자, 산술연산자, 지정 연산자, 복합지정연산자, 증감연산자 가 있다.
       관계연산자는 숫자 또는 스트링 값을 비교할 때 사용한다.
         ==            같다
         !=           같지 않다
         >             크다
         <              작다
         >=            크거나 같다
         <=            작거나 같다

        ex)
          NF != 5 { print "필드수가 5개가 아님"}
          $1 >= 10000 { print "첫번째 필드값이 10000 보다 크거나 같다" }
          $1 >= "s" { print " 첫 번째 필드가 s 보다 뒷문자(tuvw..)이다"}
          $1 < $2 { print "두번째 필드 값이 첫 번째 필드 값보다 크다"}

          패턴연산자는 스트링 패턴과의 일치 여부를 비교할 때 주로 사용 된다.
             ~             패턴과 일치
             !~           패턴과 같지 않다.
         ex)
           $1 !~ /^[0-9]+$/ { print "첫번째 필드가 숫자가 안니다" }
           $2 ~ /korea/ { print "두번째 필드값이 korea 이다"}

         산술연산자는 수식 계산에 사용된다
           +             더하기
           -             빼기
           *             곱하기
           /             나누기
          %             나누어서 남은 나머지
         지정 연산자는 오른쪽 값을 왼쪽 변수에 대입한다
          =             지정연산
         ex) a = 10
        복합 지정 연산자는 산술연산자와 지정연산자를 결합해서 사용한다
        += , -=, *=, /=, %=
        ex) a += 5 : a = a + 5 와 같은 문장이다.
        증감 연산자는 값을 1씩 증가하거나 감소 시킬 때 사용한다
        ++           1 증가
        --           1 감소
        ex)
          $ cat ex06
             END { a = 0
                       print "a++ = ", a++
                       print "a-- = ", a--
                       exit
            }
          $ cat ex07
              BEGIN { a = 0 }
          $1 > 100 { a++ }
              END { print "첫번째 필드의 값이 100보다 큰 경우는 ", a, "번입니다" }
          $
          $ awk -f ex07 data1
          첫번째 필드의 값이 100보다 큰 경우는 2 번입니다


  7) 출력문
     print 문은 출력하고자하는 문자열은 "출력내용" 의 형식으로, 변수값은 변수명을 사용하여 출력한다.
     " , " (쉼표)는 "print"문 안에서 필드를 구분한다. "" 사이의 문자열은 하나의 필드로 취급된다.
    출력방향을 조정하기위해 " > " 문자와 " >> " 문자를 사용할수 있다. 출력될 파일이름은 인용부호("")안에서 사용한다.
    ex)
    $ cat ex08
    { print $1,$2 > "sample"}
    $
    $ awk -f ex08 data1
    $ cat sample
    100 200
    300 400
    500 600
    "printf" 문을 사용하여 출력 양식을 지정할 수 있다.
   사용형식은 printf "format",expression1, expression2,..... 이다.
   format에서 변환사양은 % 기호를 붙여서 표시한다
   %d            십진수
   %o            8진수
   %x            16진수
   %s            문자열
   %f            소수
   %e            지수를 사용한 소수
   %g            %f,%e중 짧은 형태의 출력을 사용한다.
   ex)
   $ cat ex09
   $1 ~ /^[0-9]+$/ { printf "첫번째 필드 값은 %d 입니다\n",$1 }
   $
   $ awk -f ex09 data1
    첫번째 필드 값은 100 입니다
    첫번째 필드 값은 300 입니다
    첫번째 필드 값은 500 입니다
   $
     파이프(|)를 사용하여 " print"문의 출력을 UNIX 시스템 명령어의 입력으로 사용할 수 있다.
     awk 안에서 유닉스 명령과 인수를 사용하는 경우는 인용부호(" ")로 묶어서 사용한다.
   $ cat ex09
     END { print " Pipe Test ...Is it OK? " | "mail guest" }
   $
   $ awk -f ex08 data1
   $ login guest
     Welcome to guest account
    You have mail

  8) 프로그래밍 언어 구조 제어문들
  " if " 문
   ex)
    { if ( $1 < 100 && $2 > $3 )
        { print "첫번째 필드값이 100보다 작고 두 번째 필드값이 세 번째 필드값 보다 큽니다" }
    }
   ex)
    { if ( $1 > 100 || $2 >100 )
        { print "첫번째 필드값이 100보다 크거나 두 번째 필드값이 100보다 큽니다" }
    }
 
  " while " 문
    { i = 1
       while ( i <= NF )
          { print "필드수가 1개보다 작거나 같습니다" }
    }

   " for " 문
   ex)
    $ cat ex10
     { for ( a = 1 ; a <= NF ; a++ ) print NR,a ,$a }
    $ awk -f ex10 data1
     1 1 100
     1 2 200
     2 1 300
     2 2 400
     3 1 500
     3 2 600
   $
   " break "문은 순환문의 수행을 중지 시키고 순환문 밖의 문장을 수행한다
   " continue "문은 순환문의 수행을 중지하고, 순환문의 처음 조건을 테스트한다.
   " next " 문은 다음 입력 레코드를 읽어 들이고 프로그램 수행은 패턴문의 처음을 수행한다.
   " exit " 문은 프로그램 실행을 종료한다
   ex)
   $ cat ex11
     { for ( n = 1; ; n++ )
         { if ( n <= NF ) { print NR, n, $n
            continue }
          break
     } }
   $
   $ cat ex12
     NF > 2 { print NR, NF; next }
   $
   $ cat ex13
   $1 > 100 { print NR, " $2= ", $2, "$2값 오류"
     exit 99 }
   $

  9) awk에서 많이 사용되는 함수들
    " length " 함수는 주어진 문자열의 문자 개수를 반환한다. length 함수에 인수가 없으면 현재 입력 레코드의 문자수를 반환한다.
    $ cat ex14
     { print NR, "입력된 문자열의 문자수는 " , length, "개입니다" }
   $
   $ cat ex15
     { print NR, "첫번째 필드의 문자수는 ", length($1), "개입니다" }
   $
     " substr " 함수는 지정한 문자열에서 원하는 개수 만큼의 문자들을 추출하여 반환한다
   $ cat ex16
     BEGIN {
          print substr("Happy Birthday",7,9)
          exit }
    $ awk -f ex16
     Birthday
     " index " 함수는 문자열에서 지정하는 문자열이 있는 위치를 나타낸다.
     문자열에서 지정한 문자열이 포함되어 있지 않은 경우는 0 값을 반환한다.
    $ cat ex17
      BEGIN {
            print index("Hello This is Kim","This")
            exit
      }
    $ awk -f ex17
      7
    $
      " sprintf " 함수는 printf함수와 사용방법이 유사하지만 출력의 방향이 지정연산자의 왼편에 있는 변수명이다.
    $ cat ex18
     { var = sprintf("출력연습 : 첫 번째 필드 : %d ",$1)
        print var
     }
   $
   $ awk -f ex17 data1
     100
     300
     500
   $

  ※ awk 함수들

 

  •  문자열 연산
    •  gsub(reg,s)
      입력 문자열의 전반에 걸쳐 정규표현식 r을 문자열 s로 대치한다
    • gsub(reg,s1,s2)
      문자열 s2에서 정규표현식 r을 s1으로 대치한다 
    • index(s1,s2)
      s1에서 s2의 위치를 넘겨준다  만약 없다면 0을 넘겨준다 
    • length(arg)
      인자의 길이를 넘겨준다 
    • match(s,r)
      문자열 s에서 정규표현식 r과 매칭되는 부분의 위치를 넘겨준다 
    • split(string,array[,seperator])
      구분자를 기준으로(지정하지 않으면 공백 기준)해서 지정한 문자열을 배열로 만든다  배열[1],  배열[2], ....... 
    • sub(r,s),  sub(r,s1,s2)
      gsub과 동일하다
      단지 정규표현식과 일치하는 문자열이 여러개라도 처음 문자열만 대치된다
    • substr(s,m)
      문자열 s에서 m번째 위치에서 끝까지의 문자를 리턴한다 
    • substr(s,m,n)
      문자열 s에서 m번째 위치에서 n번째까지의 문자를 리턴한다 
    • tolower(str)
    • toupper(str)
  • 수치 연산
    • atan2(x,y)
      y/x의 arctangent값을 라디안 단위로 넘겨준다 
    • cos(x)
    • exp(arg)
    • int(arg)
    • log(arg)
    • rand()
      0과 1사이의 난수를 발생한다 
    • sin(x)
    • sqrt(arg)
    • srand(expr)
      인자를 가지고 난수를 발생한다
      인자가 주어지지 않으면 시간을 가지고 난수를 발생한다 
  • 입출력/프로세스
    • close(filename)
      지정한 파일을 닫는다 
    • close(cmd)
      지정한 명령어 파이프를 닫는다 
    • delete array[element]
      지정한 배열 요소를 지운다 
    • getline()
      다음 레코드를 읽어 들인다 
    • getline[variable] [< "filename"]
      파일에서 읽어들인다 
    • next
      다음 레코드(라인)을 입력받는다
      getline()과 유사하지만 /패턴/동작을 새롭게 시작한다
      getline()은 다음 라인을 읽기만 한다 
    • print [args] [> "filename"]
      인자를 출력한다 
    • printf "format" [,expressions] [> "filename"]
      형식에 맞춰 출력한다 
    • sprintf (format [,expressions])
      printf와 마찬가지로 사용하는데 값을 리턴하기만 하고 출력은 하지 않는다 
    • system(command)
      시스템 내부 명령어를 실행한다
  • 'IT > shell 위 댄스' 카테고리의 다른 글

    배열 활용  (0) 2008.02.27
    파일 처리  (0) 2008.02.27
    date 매뉴얼  (0) 2008.02.27
    쉘로 작성한 ftp 활용  (0) 2008.02.27
    sed  (0) 2008.02.27
    블로그 이미지

    쩐의시대

    나답게 살아가고 나답게 살아가자

    ,