반응형

 1. awk ?
awk는 데이터 양식이나 문서나 혹은 자료를 처리하여 다른 형태의 문서 또는 결과물을 출력하는데 사용한다.

2. awk 의 구조
  - 시작 (BEGIN) : 입력데이터를 실행하기에 적합한 형태로 바꾸어 주는 단계
  - 실행 (Routine) : 잘 덩리된(정규화된) 데이터를 실제 루틴으로 처리하는 단계
  - 종료 (END) : 데이터가 처리된 후에 결과의 추가 출력

3. awk 의 사용
일반적으로 grep 과 같이 사용된다.

  1. grep 을 이용하여 데이터 파일의 구조 확인
  2. 정규화가 가능하지를 확인하고 sed로 테스트 한후에 awk 가 처리할수 있을정도로 
     정규화되있다면 awk를 사용
  3. sed로 정규화된 양식을 awk 로 처리

■■■■ ■■ ■■■■ ■ ■■■■■■■ ■
■■ ■■ ■■ ■■ ■■■■■■■■■ ■■
■■■■■■■■■■ ■■ ■■ ■■ ■ ■ 

위의 데이터 형식은 아래의 형식으로 바뀌게 된다.
R1  ■■■■                ■■ ■■■■ ■    ■■■■■■■      ■
R2  ■■                     ■■ ■■      ■■ ■■■■■■■■■ ■■
R3  ■■■■■■■■■■ ■■ ■■      ■■ ■                     ■ 
      F1                      F2   F3        F4   F5                    F6
      $1                      $2   $3         $4   $5                    $6

만약 awk 로 위의 데이터를 출력하면

awk '{print $1}' 위의데이터
■■■■
■■
■■■■■■■■■■

이렇게 출력된다.


 

awk [option] 'script' [file]



4. awk 의 옵션

-Fc : field separator 지정 (c 가 구분자이며 기본은 공백으로 설정)
-v 변수=값 : 스크립트를 실행하기 전에 미리 변수에 값을 지정
-f : 스크립트 파일을 지정



5. awk 의 응용

패턴 {동작}
커맨드 라인에서는 패턴, 동작 전체를 단일 따옴표(')로 묶어야 한다.
 - 패턴만 있는 경우 : 패턴과 일치하는 라인을 화면에 출력
 - 동작만 있는 경우 : 모든 라인이 동작의 대상이 됨


 

패턴
- /정규식표현/ : 정규식으로 표현된 패턴과 일치 여부
- 비교연산 : 숫자, 알파벳 모두 사용가능
- 패턴 매칭 연산 : ~ 일치하는 부분 , !~ 일치하지 않는 부분
- BEGIN : 첫번째 레코드가 읽혀지기 전에 어떤 동작을 정의
- END : 마지막 레코드가 모두 읽혀진 후에 어떤 동작을 정의

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


시스템 변수

 시스템 변수  설명 
 FILENAME  현재 파일명 
 FS  입력 필드 구분
 기본 : 공백
 NF  현재 레코드 필드 갯수
 NR  현재 레코드 번호
 OFMT  숫자에 대한 출력 포맷
 기본 : $.6g
 OFS  출력 필드 구분
 기본 : 빈줄
 ORS  출력 레코드 구분
 기본 : newline
 RS  입력 레코드 구분
 기본 : newline
 $0  입력 레코드
 $n  입력 레코드의 N번째 필드
 ARGC  커맨드 라인의 인자 개수
 ARGV  커맨드 라인 인자를 포함하는 배열
 ENVIRON  환경 변수들을 모아둔 관계형 배열
 FNR  NR과 동일
 단지 현재 파일에 적용된다는 점이 다름
 RSTART  지정한 매칭 연산을 만족하는 문자열의 맨 앞부분
 RLENGTH  지정한 매칭 연산을 만족하는 문자열의 길이


 

연산자

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


 

제어문

문법 자체는 C언어의 제어문과 같다.
 - break
 - continue
 - do { Routine } while (condition)
 - exit
 - for ( init ; condition ; re ) { Routine }
 - if ( condition ) { Routine } else { Routine }
 -  while (condition) { Routine }
 - return 


 

함수

 - 문자열 함수
 
 함수명 설명 
 gsub(r, s)
 입력 문자열 전부에 걸쳐 정규식표현 r을 문자열 s로
 치환한다.
 gsub(r, s1, s2)
 입력문자열 s2 에서 정규식 표현 r을 문자열 s1 으로
 치환한다.
 index(s1, s2)
 s1에서 s2의 위치를 넘겨준다. 없다면 0
 length(arg)  인자의 길이를 넘겨준다.
 match(s, r)
 문자열 s에서 정규식표현 r과 매칭 되는 부분의 
 위치를 넘겨준다.
 split(string, array[, seperator])
 구분자를 기준으로(기본:공백)해서 지정한 문자열을 
 배열로 만든다.
 sub(r, s) , sub(r, s1, s2)
 gsub 와 동일
  정규식식표현과 일치하는 문자열이 여러개라도 
 처음 한 문자열만 치환
 substr(s, m)
 문자열 s 에서 m번째 위치에서 끝까지 문자열을 
 넘겨준다.
 substr(s, m, n)
 문자열 s 에서 m번째 부터 n번째까지의 문자열을
 넘겨준다
 tolower(string)  대문자를 소문자로 바꾼다.
 toupper(string)  소문자를 대분자로 바꾼다.


- 수학 함수
 
 함수명 설명 
atan2(x, y)
 archtangent 값
cos(x)
 cos 값
exp(x)
 자연대수 e의 제곱
int(x)
 정수형으로 반환
log(x)
 로그
rand()
 0에서 1까지의 랜덤수
sin(x)
 sin 값
sqrt(x)
 제곱근
srand(expr)
 인자를 가진 난수(없으면 시간을 가지고 난수 발생)


- 입출력 함수
 
 함수명 설명 
close(filename)
 지정한 파일을 닫는다.
close(cmd)
 지정한 명령어 파이프를 닫는다.
delete array[element]
 지정한 배열요소를 지운다.
getline()
 다음 레코드를 읽어 들인다.
getline [variable] [< "filename"]
 파일에서 읽어드린다.
next
 다음 레코드를 입력받는다.
print [args] [> "filename"]
 인자를 출력한다
printf "format" [,exp] [> "filename"]
 형식에 맞춰 인자를 출력한다.
sprintf(format [,exp])
 printf와 마찬가지로 사용되지만 값을 
 리턴하기만 하고 출력은 하지 않는다.
system(cmd)
 시스템 내부 명령어를 실행한다.



6. 예문

1에서 10까지 출력

awk 'BEGIN { for (i = 1;i<=10;i++)  print i }'



현재 디렉토리의 파일들이 이름만 출력

ls -al | awk '{print $9}'



연재 디렉토리의 파일 이름중에 소문자 알파벳이 포함된 파일명은 출력하지 않음

ls -al | awk '/^[a-z]/{ print $9  }'





 

반응형

'리눅스 쉘 스크립트' 카테고리의 다른 글

Find 응용  (0) 2019.08.21
awk 명령어 예제  (0) 2018.01.16
find 사용하기  (0) 2018.01.15
grep 으로 다중 문자열 검색  (1) 2018.01.15
grep 정규 표현식 패턴 예제 두 가지  (0) 2018.01.15
반응형

awk
데이터 처리를 위한 유닉스 프로그래밍 언어.
awk 이름의 의미는, 언어 개발자 세 명의 이름의 이니셜을 따서 만든 것..
awk가 제작된 이후 다양한 버전이 나왔는데 구버전은 awk, 새로운 버전은 nawk, GNU 버전은 gawk 라는 명령어로 사용한다.

 

awk 기본 사용법

패턴과 command로 이루어진다.
패턴 부분에는

  - 정규식이나 조건 표현식(true/false)이 올 수 있다.

    1. 정규식 예: /^hello$/
    2. 조건 표현식 예: $1 >= 0


command 부분은 
  - c언어와 마찬가지로 조건연산자, 반복연산자, 산술연산자, 논리연산자, 삼항연산자, 증감연산자, 대입연산자 등을 사용 가능하다

  - 문법 또한 c언어와 거의 유사하다.
아무 command를 지정하지 않을 경우, 패턴에 매칭된 줄을 그대로 출력하는 기본 동작을 수행한다.
command 부분은 { }로 감싼다.
command 예: { if($1 >= 0){ print "hello"; } }


정규표현식
    - 정규표현식을 사용할 때는 슬래시 /로 감싼다.
    - grep, sed와 마찬가지로 정규표현식 메타문자를 사용할 수 있다.

※  단 단어 지시자 \<\>, 캡처 \(\), 반복 지시자 \{\}는 사용할 수 없다

 

$ awk '/^Hello/' file # 정규식 /^Hello/에 매칭되는 줄을 그대로 출력한다.

Field Separator
awk는 필드 구분자를 기준으로 각 줄의 필드를 나누어 처리한다. 필드 구분자는 FS라는 이름의 내장변수로 관리되며 기본값은 탭/스페이스이다.

 

 $ cat file
Hello 1  
Hi 2      
Haha 3 

 $ awk '{print $1}' file
hello
hi
haha

 

디폴트 FS인 스페이스에 의해 필드가 나뉘었다. print 함수를 이용하여 첫 번째 필드 $1를 출력한다. command 부분은 { }로 묶는다.

 

 $ cat file
Hello 1  
Hi 2      
Haha 3 

$ awk '/hello/{print $1,$2}' file
hello 1


정규식 패턴 /hello/에 매칭된 모든 줄의 첫 번째 필드($1)와 두 번째 필드($2)를 출력한다. 이 때 $1,$2 사이에 콤마,를 사용했는데, 출력된 결과에는 콤마 대신 공백이 들어갔다. print 명령에서의 콤마는 출력 필드 구분자를 의미하는 OFS라는 이름의 내장변수의 값으로 치환되기 때문이다. OFS의 기본값은 스페이스라서 콤마 대신 스페이스가 출력되었다.

 

 $ cat file
Hello 1  
Hi 2      
Haha 3 

$ awk '$2 > 1' file
hi 2
haha 3

조건 표현식 $2 > 1이 참인 줄만 출력한다. 즉 두 번째 필드($2)의 값이 1 보다 큰 줄만 출력한다.

 

 

 $ cat file
Hello 1  
Hi 2      
Haha 3 

$ awk '{ print $0 }' file
hello 1
hi 2
haha 3

$0은 필드를 나누지 않은 상태의 전체 레코드를 의미하는 내장변수이다. 즉 줄 내용 전체가 그대로 출력된다.

 

$ awk -F: {print $1} file    # 콜론(:) 을 필드 구분자로 사용

$ awk -F'[:,]' {print $1} file    # 콜론(:)과 콤마(,)를 필드 구분자로 사용
-F 옵션을 사용하여 필드 구분자를 직접 지정할 수도 있다.

 

printf
출력 포맷을 지정하고 싶을 때는 print 대신 printf 함수를 사용한다. 사용법은 C언어의 printf와 유사하다.
printf는 print와 달리 개행(new line)처리가 되지 않으므로, 필요시 \n을 직접 명시한다.


문자 설명
%c character
%s string
%d, %ld 10진수, long 10진수
%u, %lu unsigned 10진수
%x, %lx 16진수
%o, %lo 8진수
%e 부동소수점, e-표기법
%f 부동소수점
%g 부동소수점. %e와 %f 중 적은 자릿수를 차지하는 표기법을 사용.

 

 $ cat file
Hello 1  
Hi 2      
Haha 3 

$ awk '{ printf "word is %-10s and number is %8d and %03d\n", $1, $2, $2}' file
word is hello      and number is        1 and 001
word is hi         and number is        2 and 002
word is haha       and number is        3 and 003

%-10s : 10자리의 공간에 string 출력. 대시-는 왼쪽 정렬을 의미.
%8d : 8자리의 공간에 10진수 출력. 기본으로 오른쪽 정렬.
%03d : 3자리의 공간에 10진수 출력. 남는 공간은 0으로 채움.


내장변수

위에서 언급한 FS, OFS 외에도 여러 내장변수가 존재한다.

내장변수의 이름은 대문자로 이루어져 있다.
내장변수는 패턴 및 command 내에서 사용할 수 있으며 값을 재설정 할 수도 있다.


이름 설명

ARGC       : 커맨드라인 매개변수의 갯수
ARGV       : 커맨드라인 매개변수의 배열
FILENAME : 입력 파일의 이름
FNR         : 현재 파일의 레코드 갯수
NF           : 현재 레코드의 필드 갯수
NR           : 레코드 번호
OFMT       : 숫자를 위한 출력 포맷
OFS         : 출력 필드 구분자
ORS         : 출력 레코드 구분자
RS           : 입력 레코드 구분자
RLENGTH  : match 연산자로 매칭된 부분의 길이
RSTART    : match 연산자로 매칭된 부분의 시작 위치
SUBSEP     : 배열 구분자


 

NR, NF

$ cat file
hello 1
hi 2
haha 3

$ awk '/haha/{ print NR, $1, NF }' file
3 haha 2

NR은 파일 내에서 해당 레코드의 번호를 나타내는 내장변수이다. NF은 해당 줄의 필드 갯수를 나타내는 내장변수이다.

 

OFMT
$ awk `{ OFMT="%.2f"; print 1.234567, 12E-2; }` file
OFMT는 print 함수의 출력 포맷을 지정하는 내장변수이다.

 

ARGV, ARGC
ARGV는 shell 커맨드라인에서 입력받은 매개변수가 순서대로 저장되는 내장 배열이다. nawk 에서만 지원한다.
nawk라는 명령어 자체도 매개변수에 포함되며(ARGV[0]), 명령어의 옵션들은 포함되지 않는다.
ARGC는 커맨드라인 매개변수의 갯수가 저장되는 내장 변수이다.
$ nawk -F',' '{ for(i=0; i<ARGC; i++){ print ARGV[i]; } }' filename1 filename2
nawk        # ARGV[0]
filename1   # ARGV[1]
filename2   # ARGV[2]

match 연산자 (~, tilde)
특정 필드의 값이 정규표현식에 매칭되는지 검사할 때는 ~를 사용한다. 매칭되지 않는지 검사할 때는 !~를 사용한다.

$ awk '$1 ~ /[Hh]ello/' file    # 첫 번째 필드가 Hello, hello인 레코드를 출력
$ awk '$1 !~ /^hello/{ print $1 }' file

variable
정수, 부동소수점 실수, 문자열 등을 위한 변수를 사용할 수 있다.
awk의 변수는 선언 없이 바로 사용할 수 있으며, 사용되는 형태에 따라 0이나 ““으로 초기화된다.
awk 내에서의 변수는 shell에서의 변수와 기본적으로 호환되지 않는다.

shell의 변수를 awk로 전달하기 위해서는 -v 옵션을 사용할 수 있다.

-v 옵션
-v 옵션을 통해 전달된 변수는 awk의 BEGIN 문에서 사용할 수 있다,

BEGIN
awk가 입력 파일을 처리하기 전에, 수행해야 될 전처리 동작들을 지정할 수 있다.
OFS, RS, FS 등 내장변수의 값을 변경하거나, 사용자 정의 변수의 초기화 등을 하기 위해 쓰인다.

 

  $ cat file
Hello 1  
Hi 2      
Haha 3 

 $ awk 'BEGIN{ FS=":"; OFS="\t"; } {print $1,$2 }' file
hello 1
hi 2
haha 3
$ awk 'BEGIN{ print "Hello, world!" }

BEGIN 블럭은 awk가 입력 파일을 열기 전에 수행되므로, 입력 파일 없이 BEGIN 블럭만 실행할 수도 있다.


END
입력 파일의 모든 줄의 처리가 끝난 후에, 맨 마지막으로 실행할 동작들을 지정할 수 있다.
$ awk '{print $1} END{ print "process done."; }' file
$ awk 'BEGIN{ sum = 0; } /hello/{ sum += $1; } END{ print "sum is "sum; }' file
이렇게 BEGIN, 패턴, command, END 를 모두 함께 사용할 수 있다.

 

Array in awk
awk의 배열은 연관 배열(associative array)로, key와 value를 갖는 Hash Set 이다.
변수와 마찬가지로, 미리 선언하지 않아도 바로 사용할 수 있다. (사용과 동시에 생성된다.)
배열이 사용되는 타입에 따라 0이나 빈 문자열로 적당히 초기화된다.
배열의 순회
for (item in array) {
 print array[item];
}


delete
내장 함수 delete는 배열 요소를 삭제하는데 사용한다. - delete(array[item]);

$ awk '{ arr[x++] = $2; } END{ for(i in arr){ delete(arr[i]); } }' filename
기타 내장함수

sub
정규표현식에 매칭되는 부분을 지정한 문자열로 치환한다. longest 매칭이며, 레코드 내에서 여러번 매칭되어도 맨 왼쪽의 일치하는 부분에 대해서 한번만 치환한다. 치환할 대상을 지정하지 않으면 현재 레코드 전체($0)에 대해서 치환한다.

sub(/정규표현식/, “치환할 문자열”, “치환할 대상”);
sub(/정규표현식/, “치환할 문자열”); - $0 에 대해서 치환

gsub
sub와 유사하나 레코드 내에서 정규표현식이 매칭될 때마다 치환한다.

 

index
문자열 내에서 찾는 문자열이 나타나는 위치를 리턴한다. 위치는 1부터 시작하여 계산된다. - index(“문자열”, “찾는 문자열”);

 

length
문자열의 길이(문자 수)를 구한다.

length(“문자열”)
length 문자열을 지정하지 않으면 현재 레코드 전체($0)에 대한 길이를 구한다.


substr
문자열 내에서 지정한 위치부터의 부분 문자열을 반환한다.

substr(문자열, 시작 위치);
substr(문자열, 시작 위치, 문자열 길이)


match
문자열 내에서 주어진 정규표현식에 매칭되는 패턴이 있으면 시작 위치를 반환하고, 없으면 0을 리턴한다. 추가적으로 문자열이 매칭될 경우, 패턴의 시작 위치를 내장변수 RSTART에 저장하고 부분 문자열의 길이는 RLENGTH에 저장한다. 이는 match 함수로 매칭 여부를 확인 후 substr을 사용하는데 유용하다. 단 nawk에서만 동작한다.

match(“문자열”, /정규표현식/);


split
문자열을 단어 단위로 나누어 배열에 저장한다. 필드 구분자를 지정하지 않으면, 내장변수 FS의 값이 디폴트로 사용된다.

split(문자열, 저장할 배열, 필드 구분자);
split(문자열, 저장할 배열); - 내장변수 FS의 값을 필드 구분자로 사용
$ awk 'BEGIN{ split("05/01/2016", date, "/"); print date[3]; }'
2016

int
소숫점 이하를 버리고 정수부만 반환한다.

int(x)

rand
0~1 사이의 난수를 반환한다.

rand()

 

 

반응형

+ Recent posts