AWK
- 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 변수 = 값
- 스크립트를 실행하기 전에 미리 변수를 지정하여 준다
- -f 스크립트 파일
- 스크립트를 파일에서 가져온다
- -f 옵션을 여러번 사용하여 여러개의 스크립트 파일을 동시에 불러와 지정한 파일에 적용할 수 있다
- 스크립트
- 패턴 { 동작 }
커맨드 라인에서는 패턴, 동작 전체를 단일 따옴표로 묶는다- 패턴만 있는 경우 : 패턴과 일치하는 레코드(라인)를 화면에 출력한다
- 동작만 있는 경우 : 모든 레코드(라인)가 동작의 대상이 된다
- 패턴
- /정규표현식/
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 '
지정한 파일의 짝수번째의 라인만을 출력해 준다
참고서적 : sed & awk, Dale Daugherty, O'reilly
cafe.naver.com/itpeople