ETC

[awk] 친해지기-1

nofence 2016. 11. 15. 02:05


awk 관련해서 포스팅을 해 볼까 한다. 어설프게 알고 있던 awk에 대해 이번 기회에 체계적으로 정리하는 차원에서 짜임새 있게 학습해 보도록 하자.


awk의 기본적인 구문은 다음과 같다.


Syntax:

awk '/search pattern1/ {Actions}
     /search pattern2/ {Actions}' file


구문은 아래와 같은 특성을 갖추고 있다.


1. search pattern은 정규표현식이다.

2. Actions 은 수행 되어야 할 문장이다.

3. 다양한 패턴과 액션이 수행 가능하다.

4. 파일은 기존에 존재하는 파일이다.

5. 작은 따옴표는 쉘이 특수문자를 해석하지 않도록 기능한다.



우선 테스트 파일을 생성하자.


root@rasberrypi:~/programming/awk# cat employee.txt
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000



1. awk의 기본 동작


기본적으로 awk는 파일로부터 모든 라인을 출력한다.


root@rasberrypi:~/programming/awk# awk '{print;}' employee.txt 
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000


root@rasberrypi:~/programming/awk# awk '{print}' employee.txt
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000


위 예제에서는 패턴이 주어지지 않았기에 모든 라인에 대해 출력이 되었다. 액션 값 print는 특별히 인수가 주어지지 않을 때 기본적으로 전체 라인을 출력하도록 되어 있다. 또한 액션은 중괄호로 에워싸야 한다. 액션에 대한 각 값들에 대한 구분자는 세미콜론으로서 위에서 두 행동은 동일한 결과를 보인다.


2. 매칭 되는 패턴에 관한 라인 출력하기


root@rasberrypi:~/programming/awk# awk '/Thomas/
> /Nisha/' employee.txt
100  Thomas  Manager    Sales       $5,000
400  Nisha   Manager    Marketing   $9,500


root@rasberrypi:~/programming/awk# awk '/Thomas/
/Nisha/ {print}' employee.txt
100  Thomas  Manager    Sales       $5,000
400  Nisha   Manager    Marketing   $9,500


위 예제에서는 'Thomas' 또는 'Nisha'라는 문자열이 매칭 되는 라인을 출력한다. 즉 두개의 패턴이 존재하는데, awk는 패턴에 대한 갯수와 상관없이 매칭을 비교 수행하지만 각 패턴은 개행으로써 구분 되어야 한다.



3. 특정 필드만 출력하기


awk는 다양한 내장 변수를 갖고 있다. 각각의 행에서 기본적으로 공백으로 필드를 구분 짓고 $n 변수로 각 필드 값을 취하게 된다. 만약 4개의 행으로 구성 된 파일을 가정했을 때, 각 필드는 $1, $2, $3, $4 로 각각 값이 저장 된다. $0은 모든 필드를 나타낸다. NF는 행의 총 필드 수를 의미하는 내장 변수다.


테스트 파일은 각각의 필드가 아래와 같이 구성 되어 있음을 상기해 보자.


root@rasberrypi:~/programming/awk# cat employee.txt
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000



테스트 파일에서 2번째, 5번째 필드만 출력하기는 아래와 같다.


root@rasberrypi:~/programming/awk# awk '{print $2,$5}' employee.txt
Thomas $5,000
Jason $5,500
Sanjay $7,000
Nisha $9,500
Randy $6,000



아래의 결과는 위와 동일하다.


root@rasberrypi:~/programming/awk# awk '{print $2,$NF}' employee.txt
Thomas $5,000
Jason $5,500
Sanjay $7,000
Nisha $9,500
Randy $6,000


$0 변수는 모든 필드를 나타냄을 확인한 결과는 아래와 같다.


root@rasberrypi:~/programming/awk# awk '{print $0}' employee.txt
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000


4. BEGIN과 END


awk는 BEGIN과 END라는 두 가지 중요한 키워드가 있다.

해당 키워드에 대한 구문은 아래와 같다.


Syntax: 

BEGIN { Actions}
{ACTION} # Action for everyline in a file
END { Actions }

# is for comments in Awk


BEGIN 파트는 입력으로 부터 각 행을 읽어 들이기 전에 수행 되고 END 파트는 입력으로 부터 각 행을 읽어 들이고 처리함을 완료하고 나서 각각 수행 된다.


간단하 예제를 하나 살펴 보자.


root@rasberrypi:~/programming/awk# awk 'BEGIN {print "Name\tDEsignation\t\
Department\tSalary"}
{print $2,"\t",$3,"\t",$4,"\t",$NF}
END {print "Report Generated\n--------------------------------"}' employee.txt
Name    DEsignation     Department      Salary
Thomas   Manager         Sales   $5,000
Jason    Developer       Technology      $5,500
Sanjay   Sysadmin        Technology      $7,000
Nisha    Manager         Marketing       $9,500
Randy    DBA     Technology      $6,000
Report Generated
--------------------------------


위의 예제에서 주의할 점은 탭(\t)은 반드시 쌍따옴표로 이스케이핑 해야 한다는 것이다.

이스케이핑을 안 했을시 아래와 같은 오류 메시지가 발생한다.


root@rasberrypi:~/programming/awk# awk 'BEGIN {print "Name\tDEsignation\t\
Department\tSalary"}
{print $2,\t,$3,\t,$4,\t,$NF}
END {print "Report Generated\n--------------------------------"}' employee.txt
awk: 3: unexpected character '\'
awk: 3: unexpected character '\'
awk: 3: unexpected character '\'



5. 특정 값에 대한 대소 판별


아래의 예에서는 특정 필드가 주어진 조건에 부합할 때 그에 대응 되는 값들을 출력한다.


root@rasberrypi:~/programming/awk# awk '$1 > 200' employee.txt
300  Sanjay  Sysadmin   Technology  $7,000
400  Nisha   Manager    Marketing   $9,500
500  Randy   DBA        Technology  $6,000



6. 특정 필드에 대한 조건 검사


~ 연산자는 정규표현식을 비교하는 기능을 수행한다. 매치에 성공했을 때는 그 조건을 충족하는 모든 값들을 출력한다. 아래는 4번째 필드가 Technology라는 패턴을 갖고 있는 행을 출력하는 결과이다.


root@rasberrypi:~/programming/awk# awk '$4 ~/Technology/' employee.txt
200  Jason   Developer  Technology  $5,500
300  Sanjay  Sysadmin   Technology  $7,000
500  Randy   DBA        Technology  $6,000


아래는 5번째 필드가 "5," 라는 패턴을 매칭한 결과이다.


root@rasberrypi:~/programming/awk# awk '$NF ~/5,/' employee.txt
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500


아래는 5번째 필드가 "5," 혹은 "6," 이라는 패턴을 매칭한 결과이다.


root@rasberrypi:~/programming/awk# awk '$NF ~/5,/
> /6/' employee.txt
100  Thomas  Manager    Sales       $5,000
200  Jason   Developer  Technology  $5,500
500  Randy   DBA        Technology  $6,000


7. 변수 값 증감 후 출력하기


아래의 예는 count 변수를 0으로 초기화 후 4번째 필드가 Technology이면 count를 1씩 증가 시킨 최종 값을 출력한 결과이다.


root@rasberrypi:~/programming/awk# awk 'BEGIN {count=0}
> $4 ~ /Technology/ {count++}
> END {print "Number of employee in Technology Dept =", count}' employee.txt
Number of employee in Technology Dept = 3




참고 URL :

http://www.thegeekstuff.com/2010/01/awk-introduction-tutorial-7-awk-print-examples/


'ETC' 카테고리의 다른 글

AWS 자격증 시험 일정 연기 절차  (0) 2023.04.12