2010. 1. 13. 10:34

[Script]awk 및 sed 사용법

스크립트


--------------------------------------------------------------------------------

기본적인 특수 문자에 대한 설명


  . (dot) 
      개행문자(\n, newline)를 제외한 모든 문자와 매치된다.
      단, awk에서는 라인을 (\n)만 지정하지 않으므로, 개행문자(\n)와도 매치가 된다.


 * (asterisk)
      매치되는 일반문자, 정규식문자의 숫자에 제한을 가지지 않는다( 0 ~ 무한대 ).


 [...] (brackets)
     괄호안에 있는 모든 문자와 일치하는 문자를 찾는다. 예를 들어 [aE] 라고 하면, a 또는 E 문자를 찾는다.
     - (hyphen)을 사용하게 되면, 특정 문자에서 특정 사이의 모든 문자를 가리키게 된다.
     이 괄호에서는 모든 메타문자들이 자신의 기능을 상실하게 된다. 다만 ^ 와 같은 예외의 기능을 가지는 문자들도 있다.
     ^(caret) 는 괄호 내부에서 !(not)의 기능을 가지고 있다. 예를 들어 [^ ] 는 ' '공백문자가 아닌 모든 문자를 가리키게 된다.


 ^ (caret)
     각 라인의 처음을 가리킨다. 이것은 첫번째 문자가 아니라는 걸 명심해야 한다.
     단지 각 라인의 처음이라는 것이다. awk에서는 개행문자의 다음이 아니다.


 $ (dollar)
     각 라인의 끝을 가리킨다. ^(caret)과 마찬가지로 awk에서는 개행문자 이전이 아니다.


 \{n,m\} (middle brackets)
     단일문자, 메타문자가 매치되는 갯수의 영역을 명시한다.
     \{n\} 은 정확하게 n개가 되는 것을 말하며,
     \{n,\} 은 n개 이상,
     \{,m\} 은 m개 이하를 말하며,
     \{n,m\} 은 n개 이상, m개 이하를 말한다.


 \ (back slash)
     다음에 오는 문자가 특수문자(Special Character)임을 알린다.


--------------------------------------------------------------------------------

< Vi >
Replace

: %s/boy/girl/           // edit mode에서 파일 전체행의 boy라는 글짜를 girl이라는 글짜로 바꾸는 작업.

: 5,10s/boy/girl/g      // 5행에서 10행까지 글짜 바꾸는데, 한줄에 두 번 이상 나와도 바꾸는 옵션 g.

: .,20s/boy/girl/         // 현재행 .에서 20행 까지.

: .,$s/boy/girl/           // 현재행 .에서 마지막 행까지.

: .,/man/s/boy/girl/     // 현재행 .에서 다음의 man 이라는 글짜를 포함하는 행까지.


--------------------------------------------------------------------------------

<  SED - a Stream EDitor     >
  sed   [-e script][-f script-file][file...]

기본적인 기능은 ed에서 따 왔으며, 이 기능들은 모두 sed에 적용이 된다. 다만 ed는 대화형 편집기이며,
sed는 스트리밍 편집기이다. 대화형 편집기와 스트리밍 편집기의 차이점은 대화형 편집기는 입력 및 출력이
하나로 이루어지며, 스트리밍 편집기는 하나의 입력이 하나의 출력을 낸다는 것이다.
\n 을 개행문자로 사용하는 스트리밍 에디터이다. 

 찾기(search), 출력(print),
    sed -n '/abd/p' list.txt   :  list.txt 파일을 한줄씩 읽으면서(-n : 읽은 것을 출력하지 않음)  abd 문자를 찾으면 그 줄을 출력(p)한다.

 치환(substitute),
    sed 's/addrass/address/' list.txt   :  addrass를 address로 바꾼다. 단, 원본파일을 바꾸지 않고 출력을 바꿔서 한다.
     sed 's/addrass/address/' list.txt > list2.txt
     sed 's/\t/\ /'  list.txt            : 탭문자를 엔터로 변환
    sed 's/□□*/□/'  list.txt       : ( *표시: □ 는 공백 문자를 표시한다. ) 위의 구문은 한개이상의 공백문자열을 하나의 공백으로 바꾼다.


 추가(insert)
     scriptfile  -  s/</\ /g
     sed -f scriptfile 1.html  :  < 문자부분에  \n 개행문자를 넣어서 다음줄에 출력하도록 한다.

 삭제(delete)
    sed '/TD/d' 1.html   :  TD 문자가 포함된 줄을 삭제하여 출력한다.
     sed '/Src/!d' 1.html :  Src 문자가 있는 줄만 지우지 않는다.
     sed '1,2d' 1.html    :  처음 1줄, 2줄을 지운다.
    sed '/^$/d   1.html    : 공백라인을 삭제하는 명령이다

  파일 이름만을 뽑아내는 정규식
     s/^.*\/\([a-zA-Z0-9.]*\)".*$/\1/   : ^는 라인의 맨 처음, .* 아무문자열, \(, \)은 정규표현식을 그룹화, $ 는 라인의 맨 끝.
    ( s;^.*\/\([a-zA-Z0-9.]*\)".*$;\1;)    \1는 그룹화된 첫번째 요소를 말한다.
                                                                        [a-zA-Z0-9.] 는 알파벳과 숫자 및 .(콤마)를 표현하는 문자(character)를 말한다.
       즉 GF02.jpg와 같은 문자열을 첫번째 그룹화하고 난 다음 라인 전체를 그룹화된 내용으로 바꾸는 것이다. 
  /g     : global을 의미  한줄에 대상문자가 여러개일 때도 처리하도록 한다.

 who | sed -e 's; .*$;;'    :  각 라인의 첫 번째 공백에서부터 마지막까지 삭제하라.

 who | sed -e 's;^.* ;;'     :  각 라인의 처음부터 맨 마지막 공백까지 삭제하라.

 who | sed -e 's;^.*:;;'     :  각 라인의 처음부터  : 문자가 있는 곳(:문자포함)까지 삭제하라. 

 -n 옵션
 sed는 항상 표준 출력에서 입력 받은 각 라인을 나타낸다는 것을 알아냈다. 그러나 때때로 한 파일로부터 몇 개의 라인들을 추출해 내기 위해 sed를 사용하기를 원할 때도 있다. 이러한 경우에 -n옵션을 사용한다. 이 옵션은 사용자가 만약 해야 할 일을 정확히 말해 주지 않는다면 임의의 라인을 프린트하는 것을 원하지 않는다고 sed에게 말한다. 따라서 p명령이 같이 쓰인다. 라인 번호와 라인 번호의 범위를 나타냄으로써 sed를 사용하여 텍스트의 라인들을 선택적으로 프린트할 수 있게 한다. 다음에서 볼 수 있는 바와 같이, 한 파일로부터 첫 번째 두 라인이 프린트되었다.

 $ sed  -n  '1,2p'  intro                 Just print the first 2 lines from intro file.


만약 라인 번호 대신에 슬래시로 에워 싸인 문자열과 함께 p명령이 쓰인다면 sed는 이들 문자들이 포함하고 있는 표준 입력을 통해서 라인들을 프린트하게 된다. 따라서 하나의 파일로부터 처음의 두 라인을 프린트하기 위하여 다음과 같이 사용될 수 있다.

 $ sed  -n  '/UNIX/p'  intro              Just print lines containing UNIX


   sed  '5d'                                   : 라인 5를 삭제
   sed  '/[Tt]est/d'                        : Test 또는 test를 포함하는 모든 라인들을 삭제
   sed  -n  '20,25p'  text                : text로부터 20에서 25까지의 라인들만 프린트
   sed  '1,10s/unix/UNIX/g'  intro    : intro의 처음 10개의 라인들의 unix를 UNIX로 변경
   sed  '/jan/s/-1/-5'                     : jan을 포함하는 모든 라인들 위의 첫 번째 -1을 -5로 변경
   sed  's/...//'  data                      : 각 data라인으로부터 처음 세 개의 문자들을 삭제
   sed  's/...$//'  data                    : 각 데이터 라인으로부터 마지막 3문자들을 삭제
   sed  -n  '1'  text                        : 비 프린트 문자들을 \nn으로 (여기서 nn은 그 문자의 8진수 값임),
                                                    그리고 탭 문자들을 > 로 나타내는 각 텍스트로부터의 모든 라인들을 프린트
--------------------------------------------------------------------------------


awk 명령어

--------------------------------------------------------------------------------

 awk '/west/'  datafile            :  west 라는 글이 있는 줄 출력

 awk '/^north/' datafile           :  north로 시작하는 줄 출력

 awk '/^(no | so)/' datafile     :  no 또는 so 로 시작하는 줄 출력

 awk '{ print  $3, $2 }'  datafile  : datafile 리스트의 세 번째 와 두 번째 필드를 스페이스로 띄어서 출력

 awk '{ print  $3  $2 }'  datafile  : datafile 리스트의 세 번째 와 두 번째 필드를 그냥 붙여서 출력

 awk '{ print  "Number of fields : " NF} '  datafile  : datafile의 각 줄마다의 필드수를 리턴한다.

 awk '$5 ~ /\.[7-9]+/'  datafile   :  다섯 번째 필드가 마침표 다음엣 7과 9사이 숫자가 하나 이상 나오는 레코드 출력

 awk '$2 !~ /E/ { print $1, $2 }'  datafile  : 두 번째 필드에 E 패턴이 없는 레코드의 첫 번째와 두 번째 필드 출력

 awk '$3 ~  /^Joel/{ print $3 " is a nice guy."} ' datafile  : 세 번째 필드가 Joel로 시작하면 " is a nice guy"와 함께 출력

 awk '$8 ~ /[0-9][0-9]$/ { print $8 }' datafile  : 여덟 번째 필드가 두 개의 숫자이면 그 필드가 출력

 awk '$4 ~ /Chin$/ { print "The price is $" $8 "." }' datafile   : 네 번째 필드가 Chine으로 끝나면 "The price is $" 8번 필드 및 마침표가 출력

 awk -F:  '{ print  $1 } '  datafile     : -F 옵션은 입력 필드를 ':'로 구별.

 awk -F"[ :]" '{ print  $1, $2 } ' datafile   : 입력 필드로  스페이스와 ':'를 필드 구별자로 사용

 awk -f  awk_script.file datafile     :  -f 옵션은 awk 스크립트 파일 사용할 때 씀.

 

 awk '$7 == 5'  datafile        : 7번 필드가 5와 같다면  출력

 awk '$2 == "CT" { print $1, $2 }' datafile    : 2번 필드가 "CT" 문자와 같으면 1, 2 번 필드 출력

 awk '$7 <  5  { print $4, $7}' datafile         : 7번 필드가 5보다 작다면  4번, 7번 필드 출력

 awk '$6 > .9 { print $1, $6}' datafile          : 6번 필드가 .9 보다 크다면  1번, 6번 출력

 awk '$8 > 10 && $8  < 17 ' datafile   

 awk '$2 == "NW" || $1 ~ /south/ { print $1, $2 }' datafile

 

 

 

 

 재지향 출력/입력

     파일 기술자 0 : 표준 입력
     파일 기술자 1 : 표준 출력
     파일 기술자 2 : 표준 에러 출력
     $ kill -1 1234 > killout.txt  2>&1     :  killout.txt에  표준 출력과 에러출력을 같이 하겠다는 의미.
     $ kill -1 1234  1>&2                      :  표준출력을 에러출력으로 하겠다는 의미.

 

 

gcc 컴파일 ( make 파일 )


--------------------------------------------------------------------------------

1. 의존성

     all  :  myapp myapp.1        // 여러 파일을 만들려면 가짜 대상인 all을 사용한다.

     myapp : main.o 2.o 3.o

     main.o : main.c a.h

     2.o : 2.c a.h b.h

     3.o : 3.c b.h c.h

2. 규칙

     all  :  myapp myapp.1       // 아무런 대상 명시 없이 make를 실행하면 기본행동으로  all에 있는 것을 생성한다.

     myapp : main.o 2.o 3.o

            gcc -o myapp main.o 2.o 3.o

     main.o : main.c a.h

            gcc -c main.c

     2.o : 2.c a.h b.h

            gcc -c 2.c

     3.o : 3.c b.h c.h

            gcc -c 3.c

3. 매크로

    매크로 정의 형식 :   MACRO_NAME=value

    사용 형식           :    $(MACRO_NAME) or  ${MACRO_NAME}

        CC=gcc

        INCLUDE=.

        CFLAGS=-g -Wall -ansi

        all  :  myapp myapp.1      

        myapp : main.o 2.o 3.o

            $(CC) -o myapp main.o 2.o 3.o

        main.o : main.c a.h

            $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c

        2.o : 2.c a.h b.h

            $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c

        3.o : 3.c b.h c.h

            $(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c

4. Clean & Install

        INSTDIR=/usr/local/bin

        clean  :                             // 어떤 의존성도 없으므로 적을 것이 없다.

             -rm main.o 2.o 3.o       // make 명령은 -로 시작하는 명령의 결과를 무시한다. 그래서 make clean은 무조건 성공했다고 간주한다.

        install  :  myapp                // install을 위한 명령을 수행하기 전에  myapp를 먼저 생성해야 한다는 것을 의미

        @if [ -d $(INSTDIR) ]; \    // @로 시작되는 줄은 표준 출력하지 않는다.

                then \

                cp myapp $(INSTDIR); \

                chmod a+x $(INSTDIR)/myapp; \

                chmod og-w $(INSTDIR)/myapp; \

                echo "Installed in $(INSTDIR)"; \

          else \

                echo "Sorry, $(INSTDIR) does not exist"; \

          fi

5. 내장(Built-in) 규칙

        make는 내부에 기본 규칙을 매크로를 사용하여 가지고 있다.

        OUTPUT_OPTION = -o $@           //  $@  현재 대상의 완전한 이름

        COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

        .c.o :                     // c로 끝나는 파일로부터 o로 끝나는 파일을 만든다는 규칙.

             $(COMPILE.c) $< $(OUTPUT_OPTION)

6. 접미사 규칙

     형식 : .< 소스접미사>.<결과접미사>:

        all : myapp

        .SUFFIXES : .cpp

        .cpp.o :                 // cpp 파일로부터 오브젝트 파일 만들어내는 규칙. (유닉스는 c++파일에 대해 cpp가 아닌 cc로 끝내는 것이 관례)

             $(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<      // -xc++은 gcc에게 소스파일이 C++ 파일임을 말해줌.

                                                                                    //  $< 는 시작하는 파일명 즉 소스 파일명으로 확장되는데,

                                                                                    //                    의존하고 있는 대상보다 최신의 파일 하나.

                                                                                    //  $?  의존하고 있는 현재 대상 중 최신의 것들

                                                                                    //  $*  접미사를 제외한 대상 파일의 이름.

 출처 : http://ai.korea.ac.kr/~kaizer/unix/scripts.htm