본문 바로가기
IT/linux

linux awk 사용법과 예제 설명

by 어느해겨울 2021. 12. 29.

awk(오크; Aho Weinberger Kernighan)

 - awk의 기본 기능은 텍스트 형태로 되어있는 입력 데이터를 행과 단어 별로 처리해 출력하는 것

 

 

1.  사용법

 Usage:
  awk [POSIX or GNU style options] -f progfile [--] file ...
  awk [POSIX or GNU style options] [--] 'program' file ...

 Examples:
  awk '{ sum += $1 }; END { print sum }' file
  awk -F: '{ print $1 }' /etc/passwd

 

 

2.  설명

 - awk패턴 처리 명령어로 직접 사용자로부터 입력을 받거나 지정한 파일을 가공하여 표준 출력한다.

 - 표준 출력을 리다이렉션 할 수 있다.

 - 검색 패턴은 grep 명령보다 일반적이며, 사용자가 입력 텍스트 라인에서 여러 작업을 수행할 수 있다.

 - 컴파일이 필요로 하지 않고 변수, 숫자 함수, 문자열 함수 및 논리 연산자를 사용할 수 있다.

 

 

3. 기본 사용 패턴

3.1. 파일에서 입력을 받아들일 때

  awk 'pattern' filename

  awk '{ action }' filename

  awk 'pattern { action }' filename

 

3.2. 커맨드에서 입력을 받아들 때

  command | awk 'pattern'

  command | awk '{ action }'

  command | awk 'pattern { action }'

 

 

4. 옵션

4.1. 내장 변수

키워드 설명
FILENAME  현재 입력파일의 이름
$0 입력 레코드
$n 입력 레코드의 N번째 필드
ENVIRON 환경변수를 모아둔 관계형 배열
NR 출력 순번 
NF 현재 줄의 필드수
ARGC 명령줄 인자의 개수
ARGV 명령줄 인자들의 배열
FNR 현재파일에서의 레코드 번호
FS 입력 필드 구분자
OFMT 숫자들의 표현형식
OFS 출력필드 구분자
ORS  출력 레코드 구분자
RS 입력코드 구분자
EP 서브스크립트의 구분자
RLENGTH match 함수로 일치하는 문자열의 길이
RSTART match 함수로 일치하는 문자열의 오프셋

4.2. awk 옵션

옵션 설명
-u 버퍼를 사용하지 않고 출력한다.
-F  확장된 정규 표현식으로 필드구분자를 지정한다, 다중 필드 구분자 사용 가능하다.
awk -F 단일로 사용시 ':' 를 필드구분자로 사용
awk -F'[ :\t]' 다중 필드구분자 ':'와 tab을 필드구분자로 사용
-v 스크립트를 실행하기 전에 미리 변수를 지정하여 준다.
-f awk 명령 스크립트를 파일에서 읽어온다.

 

 

5 스크립트

5.1 패턴 { 동작 }

  커맨드 라인에서는 패턴, 동작 전체를 단일 따옴표로 묶는다.

  패턴만 있는 경우 : 패턴과 일치하는 레코드(라인)를 화면에 출력한다.

  동작만 있는 경우 : 모든 레코드(라인)가 동작의 대상이 된다.

 

  5.1.1. /정규표현식/

  sed가 지원하지 않는 +, ?, |, ( ) 등의 메타 문자도 지원한다.

  또한 ^, $를 각 필드의 처음과 끝을 의미하도록 사용할 수도 있다.

 

  5.1.2. 비교연산

  숫자 기준, 알파벳 기준 모두 사용 가능하다.

 

  5.1.3. 패턴 매칭 연산

  ~    :  일치하는 부분을 나타낸다.

  !~   :  일치하지 않는 부분을 나타낸다.

 

  5.1.4. BEGIN

  첫 번째 레코드가 읽히기 전에 어떤 동작을 정의하여 사용하고 싶을 때 사용한다.

 

  5.1.5. END

  마지막 레코드가 모두 읽힌 후 어떤 동작을 정의하여 실행하고 싶을 때 사용한다.

 

5.2. 동작

  동작은 모두 { }로 둘러싸야한다.

  예제)

  1) good이라는 문자열을 포함하는 모든 레코드를 출력

   : /good/

 

  2) 각 레코드의 첫 번째 필드를 출력

   : { print $1 }

 

  3) Good이라는 문자열을 포함하는 레코드의 첫 번째 필드를 출력

   : /good/ { print $1 }

 

  4) 두 개 이상의 필드를 가지는 레코드를 전부 출력

   : NF > 2

 

  5) 한 라인(\n)을 필드로, 빈 라인("")을 레코드로 구분

   : BEGIN { FS = "\n" ;  RS = ""}

 

  6) 첫번째 필드가 good와 일치하는 레코드에 대해 세번째 필드를 먼저 출력하고 두번째 필드를 나중에 출력

   : $1 ~ /good/ { print  $3 ,  $2 }

 

  7) good이라는 문자열이 몇 개나 들어가 있는지 계산하여 마지막 부분에서 출력

   : /good/ { ++x } END { print x }

 

  8) 두 번째 필드를 모두 합하고 마지막 부분에서 두 번째 필드의 총합계를 출력

   : { total += $2 } END { print "Total of $2: " ,  total } 

 

  9) 레코드의 길이가 20자 이하인 것을 출력하고 싶을 때

   : length($0) < 20 

 

  10) 네 개의 필드를 가지며 good이라는 단어로 시작하는 모든 레코드를 출력

   : NF == 4  &&  /^good/

 

  11) 빈 줄을 제외한 모든 줄을 화면에 출력

   : NF > 0

 

 

6. 연산자

연산자 설명
산 술 =, +=, -=, *=, /=, %=
조 건 ?, :
논 리   ||, &&, !
패 턴 ~, !~
비 교 <, <=, >, >=, !=, ==
증 감 ++, --
필드참조 $

 

 

7. 제어문

 while  continue  break
 do {실행} while (조건)  for(관계형 배열의 요소) {실행}  if(조건) {실행} else {실행}
 return               Exit  

 

 

8. 명령어

8.1. 문자열 연산

  1) gsub(reg, s)

   : 입력 문자열의 전반에 걸쳐 정규표현식 r을 문자열 s로 대치한다.

  2) gsub(reg, s1, s2)

   : 문자열 s2에서 정규표현식 r을 s1으로 대치한다.

  3) index(s1, s2)

   : s1에서 s2의 위치를 넘겨준다  만약 없다면 0을 넘겨준다.

  4) length(arg)

   : 인자의 길이를 넘겨준다.

  5) match(s, r)

   : 문자열 s에서 정규표현식 r과 매칭 되는 부분의 위치를 넘겨준다.

  6) split(string, array [, separator])

   : 구분자를 기준으로(미지정 : 공백 기준)해서 지정한 문자열을 배열로 만든다. 배열[1],  배열[2], ....... 

  7) sub(r, s),  sub(r, s1, s2)

   : gsub과 동일하다. 단지 정규표현식과 일치하는 문자열이 여러 개라도 처음 문자열만 대치된다.

  8) substr(s, m)

   : 문자열 s에서 m번째 위치에서 끝까지의 문자를 리턴한다.

  9) substr(s, m, n)

   : 문자열 s에서 m번째 위치에서 n번째까지의 문자를 리턴한다.

  10) tolower(str)

   : 문자열의 대문자를 소문자로 변환.

  11) toupper(str)

   : 문자열의 소문자를 대문자로 변환.

 

8.2. 수치 연산

  1) atan2(x, y)

   : y/x의 아크 탄젠트 값을 라디안 단위로 넘겨준다.

  2) cos(x)

   : x의 코사인 값을 넘겨준다.

  3) exp(arg)

   : 자연로그 e의 arg승을 리턴한다.

  4) int(arg)

   : 정수형으로 리턴한다.

  5) log(arg)

   : 밑이 자연 로그인 arg의 값을 리턴한다.

  6) rand()

   : 0과 1 사이의 난수를 발생한다.

  7) sin(x)

   : x의 사인 값을 넘겨준다.

  8) sqrt(arg)

   : arg의 제곱근(루트)을 리턴한다.

  9) srand(expr)

   : 인자를 가지고 난수를 발생한다. 인자가 주어지지 않으면 시간을 가지고 난수를 발생한다.

 

8.3. 입출력/프로세스

  1) close(filename)

   : 지정한 파일을 닫는다.

  2) close(cmd)

   : 지정한 명령어 파이프를 닫는다.

  3) delete array[element]

   : 지정한 배열 요소를 지운다.

  4) getline()

   : 다음 레코드를 읽어 들인다.

  5) getline[variable] [< "filename"]

   : 파일에서 읽어 들인다.

  6) next

   : 다음 레코드(라인)를 입력받는다. getline()과 유사하지만 /패턴/동작을 새롭게 시작한다.

    getline()은 다음 라인을 읽기만 한다.

  7) print [args] [> "filename"]

   : 인자를 출력한다.

  8) printf "format" [,expressions] [> "filename"]

   : 형식에 맞춰 출력한다.

  9) sprintf (format [,expressions])

   : printf와 마찬가지로 사용하는데 값을 리턴만 하고 출력은 하지 않는다.

  10) system(command)

   : 시스템 내부 명령어를 실행한다.

 

9. 예제

# USERDOC.txt
1호선    1234
4호선    5678
5호선    0987
6호선    6543
9호선    1357
 
1) 해당줄에 3이 포함되는 행번호와 내용 출력
# 순서 문자열 (문자열은 쌍따옴표안에 와야한다.)
# 행번호 , 두번째 필드 , 첫번째 필드 , 필드카운트
# $0은 해당줄의 전체 내용을 표시한다.
명령) 
awk '/3/{ print "ROW: " NR, $2, $1, NF }' USERDOC.txt

결과)

ROW: 1 1234 1호선 2
ROW: 4 6543 6호선 2
ROW: 5 1357 9호선 2

* print외에도 printf사용가능 printf는 C출력 형식을 따라 사용하면 된다.
 
 
2) Hello 순번 두번째 필드, 첫번째 필드 출력
# %d부에 문자열이오면 0으로 표시된다.
명령)
 
awk '{ printf "Hello %s %04d,%s\n", NR, $2, $1 }' USERDOC.txt

결과)

Hello 1 1234,1호선
Hello 2 5678,4호선
Hello 3 0987,5호선
Hello 4 6543,6호선
Hello 5 1357,9호선

* print사용시 필드를 쉼표로 구분하지 않으면 붙어서 나온다.
* 여기서 사용된 쉼표는 OFS에 설정된 값이며 변경 가능하다.
 
 
3) 호선과 차량번호 타이틀과 txt내용을 모두 출력하고 END LINE 출력
# BEGIN 패턴은 awk가 입력줄을 처리하기 먼저 실행시켜주는 액션블럭을 가진다.
# BEGIN 액션부에서는 OFS , RS , FS등의 내장변수의 값을 지정할 수 있다.
# END 패턴은 모든 수행이 종료된후  처리됨.

명령)
awk 'BEGIN{ print "호 선 차량번호"}{print $0}END{ print "--- END LINE ---"}' USERDOC.txt

결과)

호 선   차량번호
1호선   1234
4호선   5678
5호선   0987
6호선   6543
9호선   1357
--- END LINE ---
 
 
4) 첫번째 필드에 4가 포함되는 행의 첫번째 행만을 출력
명령)
awk ' $1 ~ /4/{print $1 } ' USERDOC.txt
 
결과)
4호선

 
5)  1호선에 해당되는 행부터 0987에 해당되는 행까지 혹은 끝까지 출력
명령) 
awk '/1호선/,/0987/' USERDOC.txt
 
결과)
1호선   1234
4호선   5678
5호선   0987

 

awk 예제 모음)

https://blog.muabow.com/367

 

linux awk 예제

awk 예제 1. 파일에서 특정 문자열 검색 $ awk '/search_string/ {print}' filename.txt : filename.txt 파일에서 "search_string"이라는 문자열을 검색하고, 해당 문자열이 포함된 모든 행을 출력 2. 파일에서 특정 열

blog.muabow.com

 

댓글