egrep

■ egrep 메타문자 요약

 

한 개의 문자에 매치시키기 위한 아이템

.

임의의 한 문자에 매치됨

ex) egrep?'2005.01.05'?file

2005, 임의의 한 글자, 01, 임의의 한 글자, 05에 매치

<2005/01/05, 2005-01-05, 2005.01.05>

[...]

문자클래스

열거된 임의의 문자에 대응됨

ex) egrep?'gr[ea]y'?file

g, r, e(or)a, y에 매치 <grey, gray>

[^...]

부정형 문자클래스

열거되지 않은 임의의 문자에 매치

ex) egrep?'pu[^t]'?file

p, u 뒤에 t가 오지 않는 행만 매치

\char

이스케이프 처리된 문자

char이 메타문제이거나 이스케이프 처리된 내용에 별도의 특별한 의미가 없다면 char문자에 매치 또는 새로운 메타문자를 정의함

ex) egrep?'\$[0-9]+'?file

행의 마지막을 의미하는 $의 의미를 그냥 돈의 단위인 $로 매치시킴 <$40>

 

뒤에 붙어서 '숫자를 세는' 역할을 하는 아이템

?

물음표

한번 나올 수 있지만 없어도 됨

ex) egrep?'html?'?file

h, t, m 뒤에 l이 나올 수도 있고 나오지 않아도 되는 행에 매치 <html, htm>

*

별표

반복회수에 제한이 없으며 아예 없어도 됨

ex)

egrep?-i?'<hr(?+size?*=?*[0-9]+)??*>?file

?이 한번이 나와도 되고 아니면 나오지 않아도 됨 즉 <hr size = 14 > (or) <hr size=14> 등의 스크립트에 매치

+

플러스

적어도 하나 있어야 되며 숫자에 제한이 없음

ex) 

egrep?-i?'<hr(?+size?*=?*[0-9]+)??*>?file

?이 한번 이상 나오는 경우에 적용됨 즉 htm 스크립트에서는 절대로 hrsize라고 붙여쓰지 않음을 말함 또, [0-9]는 숫자 하나에 대응하지만 숫자가 하나이상 나올 수 있음을 의미

min,max

주어진 범위

최소값과 최대값 사이에서 회수가 제한됨

 

위치에 매치되는 아이템

^

캐럿

행 시작되는 위치에 매치됨

ex) egrep?'^cat'?file

c, a, t으로 시작하는 행만 매치

$

달러

행 끝나는 위치에 매치됨

ex) egrep?'cat$'?file

c, a, t으로 끝나는 행만 매치

\<

단어 앞경계

단어의 시작 위치에 매치됨

ex) egrep?'\<cat'?file

c, a, t으로 시작하는 단어만 매치

\>

단어 뒤경계

단어의 끝 위치에 매치됨

ex) egrep?'cat\>'?file

c, a, t으로 끝나는 단어만 매치

 

기타

|

선택(or)

"|"로 분리되는 표현식 중 하나에 매치됨

ex) egrep?-i?'^(from|to)'?file

f, r, o, m이나 t, o로 시작하는 행에 매치

(...)

괄호

① 선택의 범위를 제한하거나 ② 수량자가 적용되는 그룹을 지정하거나 ③ 백레퍼런스를 쓸 때 위치를 지정하기 위한 메타 문자

ex) egrep?-i?'^(from|to)'?file

^의 선택범위를 제한하기 위해서 사용됨

\1, \2

백레퍼런스

앞에서 첫 번째, 두 번째,... 등의 괄호 안에서 매치된 텍스트에 매치됨

ex) egrep?-i?'\<([a-z]+)?+\1\>'?file

\1은 ([a-z]+)에 매치 <옆의 예는 중복단어 체크 매치시키는 표현식>



■ 앞의 표를 이해하는데 유의사항

 

  1. 이탤릭체로 적은 것은 egrep의 버전에 따라서 적용을 시킬 수 있는 경우가 있고 없는 경우가 있으니 주의해서 사용하기 바란다.


  2. ?는 공백의 의미를 사용했다. 이해하는데 무리가 없을 것이다.



■ 생각하는 방식을 바꾸자

ex> egrep 'cat' file

cat이라는 말에 매치되는 행을 찾는 것이 아니라 c 다음에 a 다음에 t가 나오는 행과 매치시키는 것이라고 이해하는 것이 정규표현식을 이해하는 첫걸음이다. 그리고 공백문자를 일반적인 a, b라는 문자와 똑같이 취급을 해야 한다. 공백문자는 컴퓨터는 특별한 무언가로 여기지 않는다.



■ 정규표현식은 언어다. 우리가 어떤 언어를 배우던지 자꾸 써보고 연습해 보는 것이 중요하듯이 정규표현식도 마찬가지다. 그래서 다양한 방법으로 표현된 정규표현식을 익히는 것이 중요하다.



■ grep에서 매칭을 진행하기 전에 일반적으로 \n인 줄바꿈 문자를 잘라내고 진행한다. 그래서 vi 편집기에서 찾을 수 있는 \n은 grep 에서는 찾을 수 없다.



■ 어떤 문자가 메타문자인지 아닌지는 정규표현식에서 문자가 있는 위치가 결정한다. 예를 들어서 *는 메타문자이지만 \* 인 경우는 escape된 경우이므로 메타문자가 아니다. 또 ^의 경우는 행의 제일 앞을 뜻하나 [^...] 의 경우에서는 ...에 매치되는 문자를 제외한 모든 문자에 매치시킨다. 한 가지의 예를 더 들어보자. -의 경우는 [a-z] 안에 있을 경우는 범위를 나타내지만 []밖에 있을 때는 그냥 -문자에 대치된다.




■ 지나치게 자세하게 찾으려는 표현식은 실용성을 떨어뜨린다.

  우리가 보통 날짜를 나타날 때 2005/01/05 또는 2005.01.05 또는 2005-01-05으로 나타내는데 그래서 우리는 위의 세 가지의 경우를 매치시키기 위해서 다음과 같은 정규표현식을 사용할 것이다.  ex> egrep '2005[./-]01[./-]05' file  그렇게 한다면 우리는 정확히 위의 세 가지 표현에 정확히 매치시킬 수 있지만 다소 타이핑의 수가 많아지게 된다. 그래서 우리는 다음과 같은 차선책을 택할 수 있다. ex> egrep '2005.01.05' file  경제적으로 찾을 수 있다. 하지만 이 표현식의 경우는 다음과 같은 위험이 따른다. 만약 2005901?05345 라는 일정한 배열의 숫자가 있다면 이 행도 찾는 결과를 가져온다. 따라서 우리는 경우에 따라서 정확성과 경제성 사이에서 적절하게 선택을 할 필요가 있다.



■ 위의 표현식이 모든 프로그램이나 편집기에 적용된다는 생각은 하지 말도록 부탁한다. 다른 프로그램에서는 좀 더 복잡한 형태로 정의된다. 다른 프로그램에서 정규표현식을 사용할 경우는 반드시 실험적으로 사용하고 난 뒤에 사용하거나 reference를 참고해서 사용해야 한다.



■ 문자클래스[]는 정규표현식 언어와 전혀 상관없이 별도의 메타문자를 사용



■ 이스케이프 처리되는 경우는 다음의 세 가지의 경우로 나눌 수 있다.


  1.  뒤에 메타문자를 사용하면 그 문자 자체가 가지는 형태로 매치된다. 예를 들어서 \* 라고 쓰면 스크립트 상에 있는  * 에 매치된다.


  2.  뒤에 메타문자가 아닌 문자를 쓰면 언어(language)에 따라서 다른 의미를 가지는 메타문자가 된다. 예를 들어 \< 이면 단어의 시작을 의미하는 메타문자가 된다.


  3.  뒤에 일반적인 문자가 오면  의 의미는 없는 것으로 치부해도 된다. 하지만 \1 , 의 경우는 백레퍼런스로 사용된다.



awk

■ awk란

  ? awk는 두 가지 측면을 가지고 있다. 하나는 단순한 Text 편집기로서의 측면과 좀 더 복잡한 연산을 수행하는 프로그램의 측면으로 나눌 수 있다. awk 하나만 잘 해도 웬만한 정도의 C program을 대신할 수 있을 정도의 힘을 가질 수 있다. (C program과 문법이 비슷하다.) 본론으로 들어가기 앞서는 왜 awk가 의미하는 것이 무언인지 알아야 하지 않을까. awk 는 Aho, Weinberger, and Kernighan 이 세 분의 initial을 따서 이름한 것이다. 그럼 본론으로 들어가서......



■ awk 둘러보기

  ? 다음은 예제 파일들이다.

    (파일명 : exe4.txt)

    

  gold     1    1986  USA                 American Eagle

  gold     1    1908  Austria-Hungary     Franz Josef 100 Korona

  silver  10    1981  USA                 ingot

  gold     1    1984  Switzerland         ingot

  gold     1    1979  RSA                 Krugerrand

  gold     0.5  1981  RSA                 Krugerrand

  gold     0.1  1986  PRC                 Panda

  silver   1    1986  USA                 Liberty dollar

  gold     0.25 1986  USA                 Liberty 5-dollar piece

  silver   0.5  1986  USA                 Liberty 50-cent piece

  silver   1    1987  USA                 Constitution dollar

  gold     0.25 1987  USA                 Constitution 5-dollar piece

    (파일명 : exe5.txt)

    

12;466;125;567;0.435

35;366;454;422;0.4565

35;36;45;42;0.45

34;45;235;236;0.454

567;55;233;446;0.56

34;0.53

    ex1) awk '/gold/' exe4.txt

      gold라는 문자를 가진 행을 출력한다.

    ex2) awk '/gold/ {print $5,$6,$7,$8}' exe4.txt

      gold라는 문자를 가진 행중에서 5, 6, 7, 8 열 만 출력해 준다.




    ex3) awk '{if ($3 < 1980) print $3, "    ",$5,$6,$7,$8}' exe4.txt

      3번째 열이 1980보다 작은 행중에서 3, 5, 6, 7, 8열만 출력해 준다. (간격을 ??     ?? 벌려서 만큼 출력한다.

    ex4) awk '/gold/ {ounce+=$2 END print "sum = "ounce}' exe4.txt

      gold라는 문자를 가진 행에서 두 번째 열을 더한 값을 ounce에 저장해서 그 값을 sum = 과 함께 화면에 출력을 해 준다.



■ awk 문법


  1. TEXT 편집문으로서의 awk문법

     

문법 : awk [-F<ch>] (pgm] | -f <pgm_file> [<vars>] [- | <data_file>]

ch : field separator character (필드 구분 문자)

pgm : awk command-line program (awk 명령문)

pdm_file : file containing an awk program (awk program이 있는 파일)

vars : awk variable initialization (awk 변수 초기화)

data file : input data file (입력하는 파일)


  2. PROGRAM으로서의 awk 문법

     

#!/bin/awk

BEGIN

<search pattern 1>

<search pattern 2>

<awk program syntax>

END




■ 검색 패턴 (search pattern)

  

/The/

The를 포함하는 행을 찾아준다.

/^The/

첫 글자가 T로 시작하는 것 중에서 다음 문자가 he가 나오는 행을 찾아준다

/The$/

T h e로 끝나는 문자가 있는 행을 찾아준다.

/$/

$가 있는 모든 행을 찾아준다

/[Tt]he/

The 나 the가 있는 행을 모두 찾아준다.

/[a-z]/

a부터 z까지 한 문자가 있는 행을 찾아준다

/[a-zA-Z0-9]/

다 알죠??

/wh./

wh와 그 다음의 임의의 한 문자와 대응한다.(why, who wh2 등등)

/^[+-]?[0-9]+$/

+or -를 가지고 있거나 없는 거나(++ -- +-는 매치되지 않음) 그 다음은 숫자가 하나이상 나오는 것인데 단어가 숫자로 끝나는 것에 매치한다.

/(^Korea)|(^China)

Korea 나 China에 매치된다.



■ 내부변수

  

FILENAME

현재 입력한 파일명

FS

필드 구분자 (초기값 0)

NF

필드의 개수

NR

현재 파일의 행 번호

OFS 

output의 field separator

$0

전체 입력 파일의 필드



■ 유용한 명령들

  ex1) awk -F ";" '{print NR,$1,$2,$3,$4,$5}' exe5.txt

    필드 구분 연산자를 공백에서 ;로 바꾸어 줌으로써 awk를 연산하고 있다.

  ex2) awk '{if (NR >2) print $0}' exe5.txt

    행 수가 3이상인 행만 출력한다.




  ex3) awk '{if (NF >2) print $0}' exe5.txt

    열 수가 3이상인 행만 출력한다.

  ex4) awk '{if (length($0) >10) print FILENAME,$0}' exe5.txt

    행의 단어 수가 11이상인 행만 출력한다.

  ex5) awk '{if (length($0) >10) printf("line %2d is %5.3f %6.2f %5.3f, %5.3f %5.4f ", NR, $1,$2,$3,$4,$5)}' exe5.txt

    printf 문의 형태가 C program과 일치하는 것을 알 수 있다. 우리는 쉽게 파일에 나오는 수들의 자리 수들을 쉽게 조절할 수 있다.

  ex6) awk '{print system(ls),FILENAME,$0}' exe5.txt

    system()은 UNIX 명령문을 처리하게 해 준다. 그리고 그 처리한 결과가 정상적으로 실행이 되었다면 그 결과로써 0을 리턴해 준다. 만약 실패하였다면 다른 값을 줄 것이다.

  ex7) awk '{print toupper($1), $2, $3}' exe4.txt

    toupper()은 괄호 안에 있는 문자를 대문자로 변환을 시켜서 출력을 시켜준다.

  ex8) awk 'print {tolower($1), $2, $3}' exe4.txt

    toupper()은 괄호 안에 있는 문자를 소문자로 변환을 시켜서 출력을 시켜준다.

  ex9) awk -F ";" '{print sqrt($1), $2, $3}' exe5.txt

    $1을 제곱근 해 준 값이 출력된다. sqrt뿐만 아니라 다음의 함수들도 존재한다. 효과적으로 이용하시길... atan2(y,x) : 아크 탄젠트 y/x를 출력, cos(x), sin(x), exp(x), log(x), int(x)

  ex10) awk '/silver/ {++x END print x}' exe4.txt

    silver와 일치하는 패턴의 줄 수를 구해 주는 것이다. 이것과 똑같은 결과를 얻기 위한 명령으로는 grep ??silver?? exe4.txt | wc -l 이 있다.

  ex11) awk '$1~/silver/ {print $0}' exe4.txt

    $1에서 silver에 매치되는 행들만 출력해준다. 이 명령은 좀 더 유연한 명령을 실행시켜 명령의 완성도를 높인다고 볼 수 있다.

  ex12) awk '{gsub("from","to");print}' exe2.txt

    from을 to로 모두 치환해서 화면에 출력해 준다.

  ex13) awk -F";" '{if(($1>30) &&($2>100)) print $0}' exe5.txt

    첫 번째 열이 30보다 크고 그리고 두 번째 열이 100보다 큰 것을 출력해준다.





■ awk 프로그램 예제


  1. 합계 구하기

    #!/bin/awk

    #파일명 : sum.awk

    #첫 번째와 두 번째 열을 읽어 들여서 각각의 산술평균을 구하는 awk 프로그램

    #사용법 : awk -f sum.awk filename

     

 

BEGIN 

x_sum = 0;

y_sum = 0;

print "Xcen_image";

print "Ycen_image";

 

x_sum +=$1;

y_sum +=$2;

n++

x_average = x_sum/n ;

y_average = y_sum/n ;

 

END print "x_sum :" x_sum ;

printf("%d ", x_average);

 

print "y_sum :" y_sum;

print "y_average :" y_average;

 


  2. 중복되는 행 출력하지 않게 하기

    #!/bin/awk

    #파일명 : uniq.awk

    #첫 번째 열이 같은 행은 출력하지 않고 첫 번째 열이 다른 것이 나오는 행을 출력한다.

    #사용법 : awk -f uniq.awk filename

     

BEGIN  FS = " "

 

if (var != $1 && NR != 1)

print line

var = $1

line = $0

 

END print line



  3. 첫 번째 열을 인자로 사용하는 배열을 사용하여 같은 인자를 가지는 배열일 경우에는 그 합을 구해주기

    #!/bin/awk

    #파일명 : array.awk

    #사용법 : awk -f array.awk filename

     

 

BEGIN  FS=";"

OFS=":"

      

    total[$1] += $2;

        if( lastcategory != $1)

    printf("lastcategory != $1 ");

            print $1;

            lastcategory = $1

        printf( "       ");

        print $1,$2;

      

END     printf(" "); print "TOTALS";

        for(category in total)

 

                printf("        ");

                print category, total[category];

 


이의 사항이 있거나 질문이 있으시면 이곳으로 이메일을 보내주세요 Webmaster

Copyright ⓒ 2005 All Rights Reserved by Hahn Yi

[출처] [리눅스 awk] awk|작성자 holyruby

'OS > LINUX' 카테고리의 다른 글

쉘스크립트 Example2  (0) 2011.05.14
쉘스크립트 example  (0) 2011.05.14
YUM 사용법  (0) 2011.05.13
vi 사용하기  (0) 2011.05.03
GNU screen  (0) 2011.04.23

+ Recent posts