awk
AWK ( 오크 )는 UNIX 에서 개발 된 프로그래밍 언어 에서 CSV 파일 등의 문자 파일의 처리에 사용된다.
목차[ 숨기기 ] |
개요 [ 편집 ]
AWK는 벨 연구소 에서 UNIX 개발 과정에서 sed 나 grep 같은 텍스트 처리 도구에 연산 기능을 갖게 한 확장 도구로 개발되었다.
AWK는 간단한 스크립트를 작성하여 효율적으로 텍스트 파일을 처리하는 것을 목적으로 개발되었다. 처음에는 그다지 많은 기능은 없었지만, 보급됨에 따라, 다양한 처리를 AWK에서 실행하고자하는 사용자가 늘고, 그 희망에 응해 기능의 확장이 이루어졌다. 그 결과, 일반 프로그래밍 언어와 비교해도 손색이 없을 정도의 기능을 갖게 텍스트 처리에만 머물지 않고, 개발자도 예상하지 못했던 대규모 프로그래밍에 사용되는 같은 예도 드러났다. 한편, 본래의 텍스트 처리 도구로 취급하기 쉽고, 현재에도 CSV 또는 TSV 형식의 파일을 간단히 처리하는 등의 목적으로 널리 사용되고있다.
이름의 AWK는 개발자 인 알프레드 에이호 (Alfred A ho), 페터 와인 바가 (Peter W einberger), 브라이언 카니항 (Brian K ernighan) 3 명의 첫 글자를 따서 붙인 것으로 하지만, AWK는 "오크"라고 읽고 "에이 · 다부류 케"라고 읽고 안된다고 저자는하고있다 [1] . 또한 모든 소문자 awk하면, Unix없고 Plan9에서, AWK 인터프리터 처리 계 프로그램 자체 (다른 많은 명령과 마찬가지로 모든 문자이다)을 가리키는 그러던 수있다.
AWK의 문법 [ 편집 ]
기본 구성 [ 편집 ]
AWK 스크립트는 패턴과 액션 쌍을 정렬 한 형태가되어있다. 실행을 시작하면 먼저 BEGIN 패턴의 작업을 수행한다. 이후 입력을 읽고는, 레코드 구분자 (기본적으로 줄)까지를 하나의 레코드로 필드 구분에 따라 필드에 분할하고, 레코드 패턴과 일치하는지 확인하고 패턴과 일치하면 그 패턴에 해당하는 조치 를 실행한다. 일치하는 패턴이 여러있을 때 해당 작업이 위에서 차례로 모두 실행된다. 이 입력이 다할 때까지 반복한다. 입력이 다되면 END 패턴 작업을 수행하고 종료한다.
프로그램이 다룰 데이터 형식 은 숫자 (모든 실수 (Double)로 처리됨), 문자열 , 연관 배열 이다. 인덱스를 내부 문자열 화해 키로 사용하면 연관 배열을 일반배열 처럼도 사용.
AWK 스크립트의 기본 구성은 다음과 같다.
BEGIN { (시작 처리) } (패턴 1) { (액션 1) } (패턴 2) { (액션 2) } · · · END { (종료) }
BEGIN · END 액션은 필수는 아니다.
예를 들어, 텍스트 파일의 모든 행 중 "노다 요시히코"라는 문자열을 포함하는 행의 수를 계산하는 프로그램은 다음과 같다.
BEGIN { count = 0 } / 노다 요시히코 / { + + count } END { print ""노다 요시히코 "라는 문자열이 포함 된 행의 수는"count "행입니다. " }
또한, AWK는 아직 할당되지 않은 변수는 암시 적으로 초기화된다고 가정한다 때문에 위의 예에서 BEGIN 블록은 필수는 아니다.
패턴은 다음과 같이 시작과 끝을 정의하는 패턴도있다.
/ 시작 패턴 / / 종료 패턴 / { 액션 }
예를 들어, 다음과 같이 정의하면 "Hello"가 포함 된 행에서 "Bye"가 포함 된 행까지 (행 포함) 동안 액션이 실행 된 행이 출력된다.
/ Hello / / Bye / { print $ 0; }
변수 [ 편집 ]
AWK의 특징의 하나로서 변수가 형을 가지지 않는 것을들 수있다. 변수 선언이 필요 없으며 프로그램에서 사용되는 변수는 암시 적으로 초기화된다. 따라서 정의 변수 나 초기화되지 않은 변수를 참조해서 오류 AWK는 존재하지 않는다.
AWK는 산술과 같은 수치를 필요로하는 맥락에서 암시 적으로 값을 숫자로 변환하고, 반대로 문자열을 필요로하는 경우에는 문자열로 변환한다. 예를 들어,
a = "01" b = 2 c = "a" d = a + b e = a + b + c
같은 예에서는 d와 e의 값은 3이된다.
이러한 암시 적 변환이 편리하다 동시에 사용자의 의도하지 않은 결과를 가져올 수도있다.
또한 변수에 들어있는 것이 어느 모르겠지만 반드시 수치가 필요하다는 경우에
x + 0
같이 0을 더하거나 반대로 반드시 문자열이 필요하다는 경우에
x ""
같이 ""를 결합 시키거나이라는 이디엄이있다.
함수 [ 편집 ]
AWK는 함수를 정의하고 사용하는 것이 가능하다.
함수의 정의는 다음과 같다.
function 함수 이름 (인수 1 , 인수 2 , ...) { 문장 1 문장 2 : }
AWK 변수는 인수를 제외하고 모든 전역 변수 이며, 국소 범위의 것은 인수로 선언 된 변수이다. 따라서 기술로, 함수 정의에서 추가 인수를 선언하고 그것을 국소 변수로 사용한다는 것 열린다. AWK는 함수를 호출 할 때 실제 인수의 개수가 가인의 개수보다 적게도 생략 간주 오류로하지 않는다. 이것을 이용하여 불필요한 인수를 지역 변수로 사용하는 것이다.
function 함수 이름 (인수 1 , 인수 2 , 인수 3 , 국소 변수 1 , 국소 변수 2 , ...) { ... }
이렇게 함수를 정의하고이 함수를 호출 할 때 인수를 3 개 밖에 사용하지 않으면 국소 변수 1 이후 국소 변수로 취급. 구문의 구분은 없지만, 가독성을 향상시키기 위해 둘 사이에 충분한 공백을 삽입하는 것이 관례로되어있다.
function 함수 이름 (인수 1 , 인수 2 , 인수 3 , 국소 변수 1 , 국소 변수 2 , ...)
또한, AWK 함수는 재귀도있다.
제어 구조 [ 편집 ]
AWK의 제어 구조는 C 언어에서 유래하고, 다음과 같은 것이있다.
if
(
식)
문 Tif
(
식)
문 Telse
문 Ffor
(
식 1;
식 2;
식 3 ) 글for
(
변수in
배열)
문while
(
식)
문 Tdo
문 Twhile
(
식)
break
continue
또한, 제어 구조 외에 다음의 글이있다.
{
문장 1;
문장 2;
...;
글 N}
print
printf
return
(함수의 처리를 중지하고 함수의 호출자에게 리턴 값이 지정되어 있으면 값을 돌려 준다.)next
(다음 문장의 실행 및 이후의 패턴 처리를하지 않고 다음 레코드의 처리를 시작하는)nextfile
(현재 입력 파일의 나머지를로드하지 않고 다음 파일의 처리를 시작하는)delete
(연상 배열의 전부 내지 요소를 제거)exit
(프로그램의 실행을 종료)
AWK 처리 계 [ 편집 ]
원래 awk는 UNIX 툴 가운데 하나 였지만, 다양한 플랫폼에 이식 된 다른 현재는 Unix 용으로도 GNU AWK (gawk)를 비롯한 다른 구현이 개발되는 .
- one true awk : 에이호, 와인 바가, 카니항 의한 AWK. 하나의 진정한, 같은 느낌으로, 다른 사람과 구별하는 경우 one true awk 등 불린다. 일본에서는 부서진 느낌으로 '원조'등과도. (BSD에서는 본가 Unix와 다른 구현되어 tool도 많지만) FreeBSD 의 / usr / bin / awk 등은 이것이다. 현재도 유지되고있다.
- gawk : GNU 프로젝트의 AWK의 구현. GNU / Linux 배포판에서는 awk라는에서도 이쪽의 것이 많다. POSIX 1003.2 명령어 및 유틸리티 약관에 정해진 언어 정의에 부합하고있다. 멀티 바이트 문자 에 대한 대응이나 네트워크 연결 기능 등 기존의 awk에는없는 다수의 확장이 더 해지고있어 현재도 버전 업이 계속되고있다.
- jgawk : gawk가 멀티 바이트 문자에 대응하기 이전에 만들어진 gawk 일본어 문자 대응 확장판.
- mawk : Mike Brennan에 따르면 AWK의 구현. 원래 awk 약간 확장이 더 해지고있다.
- mawk MBCS : 키무라 코이치 (핸들 이름 Bruce)에 따르면 mawk 멀티 바이트 확장.
- a2p : AWK 스크립트를 Perl 스크립트로 변환하는 변환기. Perl 배포 키트에 포함되어있다.
참고 문헌 [ 편집 ]
- A · 에이호 · B · 카니항 · P · 와인 버거 "프로그래밍 언어 AWK" 툽판 1989 년 11 월. ISBN 4-8101-8008-5 . - "AWK book"(AWK 책) 등으로 불리고, C 언어의 K & R과 같은 취급 책이다. 일본 판은 발행소의 출판 사업 철수에 의해 처음 절판된다.
- 신기원 사 에서 복간 (2004 년 2 월, ISBN 4-7753-0249-3 )되었지만, 두 번째 절판된다 [2] .
- 유니버설 쉘 프로그래밍 연구소 에서 2010 년 1 월에 두 번째 복간 ( ISBN 978-4-904807-00-2 )이 이루어졌다 [3] .
- 시무라 히로시 · 독수리 북쪽 켄 · 니시무라克信 " AWK를 256 배 사용을위한 책 " 아스키 , 1993 년 3 월. ISBN 4-7561-0162-3 . - 아스키 256 책의 하나로, 통칭 "AWK256 책"라고도하고, 현재도 판매중인 베스트셀러이다.
- Dale Dougherty · Arnold Robbins " sed & awk 프로그래밍 개정판 " 후쿠 사키 히로 역, 라일리 · 재팬 , 1997 년 10 월. ISBN 4-900900-58-3 .
- Arnold Robbins " sed & awk 데스크톱 참조 " 후쿠 사키 히로 역, 라일리 · 재팬 , 2000 년 7 월. ISBN 4-87311-017-3 .
관련 항목 [ 편집 ]
각주 [ 편집 ]
- ^ 예 카니항 의한 "프로그래밍 언어 AWK"의 일본어 버전 서문에 보인다. 또한 같은 책의 표지에는 오오우미가라스 (GREAT AUK)가 그려져있어 이것도 그 주장의 강조이다.
- ^ http://w3.shinkigensha.co.jp/books/4-7753-0249-3.html
- ^ http://www.usp-lab.com/pub/book.awk.html
외부 링크 [ 편집 ]
- Manpages of GAWK (일본어)
- awk (1) man page (SunOS 참조 설명서)
- nawk (1) man page (SunOS 참조 설명서)
- awk (1) man page (HP-UX 참조)
- Effective AWK Programming - A User 's Guide for GNU Awk의 일본어 번역
- AWK 요약 히로사키 대학 교육 학부 교육 실천 연구지도 센터 코야마 사토시 씨
- aaa - the Amazing Awk Assembler by Henry Spencer (영어)
|
AWK(오크)는 유닉스에서 처음 개발된 일반 스크립트 언어로, 텍스트 형태로 되어있는 데이터를 필드로 구분하여 처리하는 기능을 기본으로 한다. AWK라는 이름은 이 스크립트 언어를 만든 앨프리드 에이호, 피터 와인버거, 브라이언 커니핸 세 명의 성의 앞글자를 따서 붙여졌다.
AWK는 문자열 데이터와 연관 배열(배열의 인덱스가 숫자가 아닌 임의의 값이 될 수 있는 배열), 정규 표현식을 주로 사용하는 언어이다. AWK와 sed가 결합하면 간결하면서도 강력한 스크립팅이 가능하지만 한계를 가진다. 래리 월이 AWK의 한계 때문에 펄을 개발하기도 했다. AWK는 유닉스 버전 7에 처음 등장해서 지금까지 사용되는 매우 오래된 도구로, 오늘날에는 거의 모든 유닉스 계열 운영체제에 포함되어 있는 표준 도구로 자리잡았으며 다른 운영체제에서도 사용할 수 있다.
AWK 프로그램은 기본적으로 패턴과 패턴을 처리하는 명령어 짝을 늘여놓은 모양이다. 입력으로부터 한 줄씩을 읽어서 정규 표현식으로 조건이 맞는지를 검사하고 참으로 판명되면 그 줄에 대해 명령어를 실행하는 형식이다.
목차[숨기기] |
[편집]awk 프로그램의 구조
awk는 크게 명령 파일과 주 입력 파일 두 가지 데이터를 받아 실행하게 된다. 커맨드 라인을 통해 직접 입력될 수도 있으며 미리 작성된 파일일 수도 있는 명령 파일은 awk가 입력 데이터를 어떤 규칙에 따라 처리할지를 지시한다. 주 입력파일은 보통 특정한 형식에 따라 작성된 텍스트 파일이다. 주입력 역시 실제 파일을 전달할 수도 표준입력을 통해 입력될 수도 있다. 위에서 설명한 명령 파일에 해당하는 awk 프로그램은 다음과 같은 형태의 명령이 여러 줄 이어진 모양이다.
/패턴/ { 동작 }
여기서 패턴은 정규 표현식이며, 동작은 실행명령이다. awk는 입력파일을 처음부터 한 줄씩 훑으며 주어진 패턴과 일치하는 줄을 찾으면 그 줄에서 동작에 해당하는 명령을 실행한다. 전형적인 형태와 다른 다음과 같은 명령도 awk 프로그램에서 가능하다.
- BEGIN { 동작 }
- 입력을 읽기 전에 주어진 동작을 먼저 실행한다.
- END { 액션 }
- 위와 비슷하다. 주입력을 모두 훑고 마지막에 주어진 액션을 실행한다.
- /패턴/
- 패턴에 일치하는 줄을 출력한다.
- { 동작 }
- 매 줄을 읽을 때마다 동작을 실행한다.
각 형태의 명령은 명령 파일에서 여러번 올 수 있다. 각각은 명령 파일에 쓰여진 순서에 따라 실행된다. 즉, "BEGIN" 문에 두번 온다면 앞에 있는 "BEGIN" 문이 실행된 후에 다음에 오는 "BEGIN" 문이 실행된다. 그러나 "BEGIN" 문은 다른 명령들 사이에 있더라도 다른 명령들이 실행되기 전에 실행된다. 이는 "END" 문에 대해서도 마찬가지이다.
[편집]Awk 명령어
awk 명령어는 위에서 동작이라고 쓰인 위치에 쓰여 실제 동작을 지시하는 명령어이다. awk 명령어는 함수호출, 변수값 지정, 산술계산과 이들을 조합한 어떤 것이 될 수 있다. awk는 다양한 함수들을 기본적으로 지원하고 변종에 따라 다른 기타 기능들이 들어갈 수 있다. 어떤 것은 동적 링크 라이브러리를 지원하기도 한다.
간결성을 위해서 아래 예에서 괄호({ })는 생략했다.
[편집]print 명령어
print 는 텍스트를 출력한다. 이 명령어만 달랑 쓰면,
현재 줄의 내용을 출력한다. awk에서 한 줄은 자동적으로 여러 개의 필드로 구분지어진다. (필드는 비약해 말하자면 빈칸으로 구분되는 각 문자열이다.) 필드는 print 명령에서 다음과 같이 따로따로 출력될 수 있다.
- print $1
- 현재 줄의 첫 번째 필드를 출력한다.
- print $1, $3
- 첫 번째와 세 번째 필드를 출력하며, 둘 사이에는 디폴트로 빈칸(스페이스) 하나로 주어지는 OFS (출력 필드 구분자, output field seperator)가 들어간다.
X번째 필드는 $X(X는 숫자) 로 표시되며, 특별히 $0은 줄 전체를 지정한다. 실제로 "print" 과 "print $0" 는 똑같은 결과를 가져온다.
print는 계산의 결과나 함수호출의 결과값을 뿌릴 수도 있다:
print 3+2 print foobar(3) print foobar(variable) print sin(3-2)
물론 출력은 다음과 같이 하여 표준출력이 아닌 다른 파일로 쓸 수도 있다.
print "expression" > "file name"
[편집]변수 등등
변수 이름은 정규식으로 [A-Za-z0-9_] (알파벳 대문자 A부터 Z까지, 소문자 a부터 z까지, 아라비아 숫자 0부터 9까지 그리고 밑줄)로 표현되는 문자들의 조합으로 만들 수 있다. 단 awk 의 예약어는 변수가 될 수 없다. + - * /는 각각 덧셈, 뺄셈, 곱셈, 나눗셈을 나타낸다. 문자열을 합치고 싶을 때에는 단순히 변수나 고정 문자열을 붙여 쓰기만 하면 된다. 고정 문자열은 겹따옴표로 구분되며, 세미콜론으로 문(statement)의 끝을 표시할 필요는 없다. 주석문은 첫머리에 #를 달아 표시한다.
[편집]사용자 정의 함수
C와 비슷하게, 함수 선언은 함수 이름과 함수의 인자들로 이루어진다. 다음 예를 보라.
function add_three (number ,temp) { temp = number + 3 return temp }
이 함수는 다음과 같이 쓰일 수 있다.
print add_three(36) # prints 39
함수는 함수 내부에서만 쓰이는 지역변수를 가질 수 있다. 이 지역변수는 인자 목록 끝에 포함된다. 그러나 함수를 부를 때는 이 변수 자리에 아무것도 쓰지 않는다. 이들을 구분하기 위해 함수가 넘겨받는 인자와 지역변수 사이에 빈칸을 좀 집어넣어 구분하는 것이 암묵적 약속이다.
[편집]예제
다음은 AWK로 씌여진 "Hello World 프로그램"이다.
BEGIN { print "Hello, world!" }
80자보다 글자수가 많은 줄만 출력한다. length 는 현재 줄의 길이를 가지며, 동작이 지정되지 않았을 때에는 print가 기본 동작임을 기억하라.
length > 80
파일의 낱말 수를 센다. NF 는 Number of Fields, 즉 현재 줄의 필드의 개수이며, NR 은 Number of Records 레코드의 개수인데, 각 줄이 레코드이다. 결국 입력파일의 줄 수, 빈칸으로 구분된 낱말 수, 문자수 를 출력한다.
{ w += NF; c += length} END { print NR, w, c }
첫 번째 필드의 값을 쭉 더한다.
{ s += $1 } END { print s }
낱말 빈도 계산. 입력파일
{ for (i=1; i<NF; i++) words[$i]++ } END { for (i in words) print i, words[i] }
위 소스를 word_frequency.awk 로 저장하고 애국가 가사를 입력으로 주어 실행한 결과는 다음과 같다.
$ awk -f word_frequency.awk aegukga.txt 백두산이 1 충성을 1 소나무 1 대한으로 4 마르고 1 괴로우나 1 우리가슴 1 높고 1 가을하늘 1 저 1 남산위에 1 길이 4 하느님이 1 두른 1 즐거우나 1 기상과 1 밝은 1 불변함은 1 보우하사 1 맘으로 1 대한사람 4 달은 1 우리나라 1 공활한데 1 바람 1 나라 1 이 2 우리 1 서리 1 동해물과 1 무궁화 4 철갑을 1 삼천리 4
[편집]바깥 고리
- KLDP의 간단한 한국어 설명 문서
- The Amazing Awk Assembler - Henry Spencer.
- Awk Community Portal
- Awk on flossmanuals.net
- (영어) AWK - 오픈 디렉터리 프로젝트
===================================================================================
awk는 명령어를 사용하다보면, 의외로 자주쓰는데, 지금까지 얼추 맞춰서 쓰다가 문서는 찾았습니다만, 위키에 없어서 찾은것들을 정리해서 글을 씁니다. 공개되어있는 문서를 찾아서 했기에, 절대 창작문서가 아닙니다.
1 Awk란?
2 awk의 구조(Model)
3 awk 프로그램
3.1 일반적인 awk 의 용도 및 사용방법(Using Model)
- egrep 및 grep 을 이용한 데이터 파일의 구조 확인을 한다.
- 정규화가 가능한지를 확인하고, sed로 테스트 해본다. awk가 처리할만큼 정규화가 되어 있다면, 바로 awk를 사용한다.
- sed로 정규화된 양식을 awk로 처리한다.
■■■□■■■■□■■■□■■■□■■■■■■□■■■■ |
■■■■□■■□■■■■■■■□■■■■□■■□■■■■ |
■■□■■■■■■■■■□■■□■■□■■■■■■■■□■ |
위의 데이터는 아래의 형식으로 바뀌게 된다.
record1: | ■■■ | ■■■■ | ■■■ | ■■■ | ■■■■■■ | ■■■■ |
record2: | ■■■■ | ■■ | ■■■■■■■ | ■■■■ | ■■ | ■■■■ |
record3: | ■■ | ■■■■■■■■■ | ■■ | ■■ | ■■■■■■■■ | ■ |
Field 1 | Field 2 | Field 3 | Field 4 | Field 5 | Field 6 | |
$1 | $2 | $3 | $4 | $5 | $6 |
(위의 표가 잘 이해되지 않는다면, DB 입문서 등을 읽어보도록 한다.)
3.2 Example 1 - 간단한 awk 사용
# cat exam_result.dat 박종규 95점 이억운 98점 이훈강 99점 엄성기 100점 정영원 97점 박오근 98점
# awk '{print $1}' exam_result.dat 박종규 이억운 이훈강 엄성기 정영원 박오근print 명령은 간단히 처리중에 필요한 내용을 출력하는 함수이다. "$1"은 1st(첫번째) 필드를 지시한다. 마찬가지로 점수를 출력하려면, "$1" 대신에 "$2"를 입력하면 된다. 그러면, 라인의 전체 내용을 출력하려면 어떻게 해야 하는가? "$0"를 사용하면, 라인의 전체 내용을 출력할 수 있다.
# cat sedscr s/점$// # sed -f sedscr exam_result.dat 박종규 95 이억운 98 이훈강 99 엄성기 100 정영원 97 박오근 98자 이제 계산할 수가 있을 듯 하다. 그러면, 프로그램을 짜보자.
# sed -f sedscr exam_result.dat | awk 'BEGIN{ sum = 0; print "총점 출력 프로그램"; } {sum += $2} END {print "합계 : " sum}' 총점 출력 프로그램 합계 : 587위의 내용을 설명하도록 하면 다음과 같다.
#!/bin/awk # # This Program is for Summing of exam_result. # # BEGIN : 프로그램 시작 처리 BEGIN { sum = 0; print "총점 출력 프로그램"; } # ROUTINE : 프로그램 본문 { sum += $2; } # END : 프로그램 마무리 처리 END { print "합계 : " sum; }위에서 첫줄의 #!/bin/awk는 앞으로의 내용들은 /bin/awk 프로그램을 사용해서 번역(처리)을 하겠다라는 지정 구문이다. 쉘스크립트의 "#!/bin/sh"와 같은 역할을 한다고 생각하면 될 것이다. 첫줄 이외에 "#"으로 시작하는 문장들은 모두 주석이다. 프로그램의 설명이나, 함수, 루틴에 대한 설명을 적어둔다. 각 내용은 한줄이 끝날때마다 ";"(세미콜론)을 붙여서 분리를 한다.
$ sed -f sedscr exam_result.dat | awk -f sum.awkawk 스크립트 파일을 호출할 때에는 "-f 파일이름" 옵션을 사용한다는 것을 기억해야 한다.
#!/bin/awk # # This Program is for Summing of exam_result. # # BEGIN : 프로그램 시작 처리 BEGIN { sum = 0; print "총점 출력 프로그램"; } # ROUTINE : 프로그램 본문 { sum += $2; } # END : 프로그램 마무리 처리 END { print "합계 : " sum; average = sum / NR; print "평균 : " average; }실행을 하면 아래와 같이 된다.
$ sed -f sedscr exam_result.dat | awk -f sum.awk 총점 출력 프로그램 합계 : 587 평균 : 97.8333
3.3 awk의 내부변수
FS | 필드 구분자 - Fields Seperator |
RS | 레코드 구분자 - Records Seperator |
NF | 현재 레코드의 필드수(Number of Fields) |
NR | 현재 파일에서 레코드 넘버(Number of Records) |
FNR | 입력파일이 여러개인 경우에 현재 파일에서의 NF를 표시한다. |
OFS | 출력시의 FS(Output Fields Seperator). 이 값을 변경하게 되면, 출력시의 FS 가 바뀌게 된다. |
ORS | 출력시의 RS(Output Records Seperator). 이 값을 변경하게 되면, 출력시의 RS 가 바뀌게 된다. |
3.4 Example 2 - awk 프로그램 응용
# cat cards.dat 백종규 리눅스넷(주) 부산 광역시 연제구 연산동 한창 빌딩 432호 051-851-2761 김진욱 이지시스템 서울시 서초구 방배2동 450-3 3층 02-3473-6282위의 데이터 파일은 한줄이 한 레코드가 되지 않는다는 걸 알수 있다. 한 레코드는 한줄이 비워진 줄, 즉 정규식으로 표현하자면 "\n\n"으로 구분되어 있으며, 레코드내에서 필드의 구분은 개행("\n")으로 구분된다. 따라서, 위의 데이터에서 이름과 전화번호만을 출력하고 싶다면, 다음과 같이 awk 스크립트를 작성할 수 있다.
#!/bin/awk BEGIN { RS = "\n\n"; FS = "\n"; } { print $1, $NF; }위의 스크립트에서 BEGIN 부분에서 RS와 FS를 임으로 "\n\n"과 "\n"으로 변경하였다. 또한 루틴부분에서는 첫번째 필드($1)와 마지막 필드($NF)의 내용을 출력하도록 하였다. NF현재 레코드에서 필드의 숫자를 나타낸다. 여기서 인자값을 호출하는 "$"을 붙이게 되면, 마지막 필드값이 출력이 되는 것이다.
4 또다른 요약 페이지
- awk는 직접 사용자로부터 입력을 받거나 아니면 지정한 파일을 가공하여 표준 출력한다. 표준 출력을 리다이렉션할 수 있다
- 사용법
- awk [옵션] '스크립트' [-v 변수=값] [파일(들)]
- awk [옵션] -f 스크립트 파일 [-v 변수=값] [파일(들)]
- cf) 편집 스크립트 파일의 사용법
- ed : ed -s(script) sourcefile < scriptfile
- sed : sed -f(file) scriptfile sourcefile > outputfile
- awk : awk -f(file) scriptfile sourcefile > outputfile
- 옵션
- -Fc : field separator 지정
- c는 필드 사이를 구분하는 구분자이다
- 직접 지정하지 않으면 공백을 기준으로 한다
- 시스템 변수 FS를 지정하는 것과 같은 효과를 지닌다
- -v 변수 = 값
- 스크립트를 실행하기 전에 미리 변수를 지정하여 준다
- $를 쓰지 않고 변수 이름만 쓰면 된다. C에서 #define처럼 생각하면 될 것이다.
- -f 스크립트 파일
- 스크립트를 파일에서 가져온다
- -f 옵션을 여러번 사용하여 여러개의 스크립트 파일을 동시에 불러와 지정한 파일에 적용할 수 있다
- -Fc : field separator 지정
- 스크립트
- 패턴 { 동작 }
- 커맨드 라인에서는 패턴, 동작 전체를 단일 따옴표로 묶는다
- 패턴만 있는 경우 : 패턴과 일치하는 레코드(라인)를 화면에 출력한다
- 동작만 있는 경우 : 모든 레코드(라인)가 동작의 대상이 된다
- 패턴
- /정규표현식/ sed가 지원하지 않는 +, ?, |, ( ) 등의 메타문자도 지원한다 또한 ^, $를 각 필드의 처음과 끝을 의미하도록 사용할 수도 있다
- 비교연산 숫자 기준, 알파벳 기준 모두 사용 가능하다
- 패턴 매칭 연산 ~ : 일치하는 부분을 나타낸다 !~ : 일치하지 않는 부분을 나타낸다
- BEGIN 첫 번째 레코드가 읽혀지기 전에 어떤 동작을 정의하여 사용하고 싶을 때 사용한다
- END 마지막 레코드가 모두 읽혀진 후 어떤 동작을 정의하여 실행하고 싶을 때 사용한다
- 패턴 { 동작 }
- 동작
- 동작은 모두 { }로 둘러싸야 한다
- 예제
- good이라는 문자열을 포함하는 모든 레코드를 출력할 때 /good/
- 각 레코드의 첫 번째 필드를 출력할 때 { print $1 }
- good이라는 문자열을 포함하는 레코드의 첫 번째 필드를 출력할 때 /good/ { print $1 }
- 두 개 이상의 필드를 가지는 레코드를 전부 출력할 때(비교연산) NF > 2
- 한 라인(\n)을 필드로, 빈 라인("")을 레코드로 구분할 때 BEGIN { FS = "\n" ; RS = ""}
- 첫 번째 필드가 good와 일치하는 레코드에 대해 세 번째 필드를 먼저 출력하고 두 번째 필드를 나중에 출력하고 싶을 때 $1 ~ /good/ { print $3 , $2 }
- good이라는 문자열이 몇 개나 들어가 있는지 계산하여 마지막 부분에서 출력하고 싶을 때 /good/ { ++x } END { print x }
- 두 번째 필드를 모두 합하고 마지막 부분에서 두 번째 필드의 총합계를 출력하고 싶을 때 { total += $2 } END { print "Total of $2: " , total }
- 레코드의 길이가 20자 이하인 것을 출력하고 싶을 때 length($0) < 20
- 네 개의 필드를 가지며 good이라는 단어로 시작하는 모든 레코드를 출력하고 싶을 때 NF == 4 && /^good/
- 빈줄을 제외한 모든 줄을 화면에 출력한다 NF > 0
- awk 시스템 변수
FILENAME 현재 파일명 $0 입력 레코드 FS 입력 필드 구분 디폴트 : 공백 $n 입력 레코드의 N번째 필드 NF 현재 레코드 필드 갯수 ARGC 커맨드 라인의 인자 갯수 NR 현재 레코드 번호 ARGV 커맨드 라인 인자를 포함하는 배열 OFMT 숫자에 대한 출력 포맷 디폴트 : %.6g ENVIRON 환경변수들을 모아둔 관계형 배열 OFS 출력 필드 구분 디폴트 : 빈줄 FNR NR과 동일 단지 현재 파일에 적용된다는 점이 다름 ORS 출력 레코드 구분 디폴트 : newline RSTART 지정한 매칭 연산을 만족하는 문자열의 맨 앞부분 RS 입력 레코드 구분 디폴트 : newline RLENGTH 지정한 매칭 연산을 만족하는 문자열의 길이 - awk 연산자
- 산술 : =, +=, -=, *=, /=, %= 조건 : ? : 논리 : ||, &&, ! 패턴 : ~, !~
- 비교 : <, <=, >, >=, !=,== 증감 : ++, -- 필드참조 : $
- 제어문(C의 제어문과 같다)
- break
- continue
- do {실행} while (조건)
- exit
- for (관계형 배열의 요소) {실행}
- 펄의 foreach와 같다
- if (조건) {실행} else {실행}
- return
- while
- 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) 시스템 내부 명령어를 실행한다
- 문자열 연산
- 간단한 예
- awk ' BEGIN { for (i = 1;i<=7,i++) print int(101*rand()) }' 화면에 1이상 100이하의 난수 일곱 개를 출력한다
- ls -l file1 file2 file3 | awk ' { x += $5 } ; END { print "Total bytes : " x } ' 파일들의 크기를 모두 합하여 총 바이트 수를 표시한다
- awk ' END { print NR } ' filename 지정한 파일의 라인이 몇 개인지를 표시한다
- awk ' NR % 2 == 0 ' 지정한 파일의 짝수번째의 라인만을 출력해 준다
split(string, tmp) for (var in tmp) { new[tmp[var]] = var delete tmp[var] }
출처 - http://wiki.kldp.org/wiki.php/Awk