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 예제 모음)
'IT > linux' 카테고리의 다른 글
svn external link 제외 옵션 설명과 예제 (0) | 2021.12.30 |
---|---|
정규 표현식 목록 / Regular expression sheet (0) | 2021.12.29 |
PCM device 확인 / fuser 활용하여 device busy 해결 (0) | 2021.12.29 |
alsa.conf alsa-utils reload 예제 (0) | 2021.12.29 |
시스템 로그(syslog) 종류, 비활성화 방법과 예제 (0) | 2021.12.29 |
댓글