ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • sed
    bin/script 2008. 3. 19. 14:37
    sed wiki http://en.wikipedia.org/wiki/Sed
    sed 예제 http://sed.sourceforge.net/sed1line.txt
    sed 기초 http://www.ibm.com/developerworks/kr/library/l-sed1.html
    sed 한글 http://rhdxmr.tistory.com/59
    sed kgun http://korea.gnu.org/manual/release/sed/x110.html

    sed: sequentil stream 을 처리
    sed (Stream EDitor) refers to a Unix utility for parsing text files and the programming language it uses to apply textual transformations to a sequential stream of data. It reads input files line by line, applying the operation which has been specified via the command line (or a sed script), and then outputs the line. It was developed from 1973 to 1974 as a Unix utility by Lee E. McMahon of Bell Labs, and is available today on most operating systems.
    sed 는 패턴 버퍼에 라인을 읽어 저장하고, 편집한 후 출력한다.

    치환
    single quote: 정규표현식에 쓰이는 $ 와 쉘치환이 충돌하지 않도록 - 즉 싱글 쿼트에서는 쉘 치환되지 않음
    double quote: 쉘 치환 가능
    Most often single quotes are used, to avoid conflicts with shell substitution for $ (used in regexes) and avoid needing to double-escape backslash (used in replacement strings). In other cases one may wish to use shell substitutions to allow the sed expression to be modified, such as "s/$1/$2/g" which allows a substitution command to be made from command line arguments.
    예제 http://askubuntu.com/questions/76808/how-to-use-variables-in-sed
    예제 http://stackoverflow.com/questions/11146098/bash-use-a-variable-in-a-sed-command
    변수값을 double quote 로 둘러싸서 치환할 때 double quote 앞에 슬래시 사용 \"
    $ pattern=xxx
    $ sed "s/PRUNE/$pattern/" /etc/updatedb.conf
    xxxFS="sysfs selinuxfs  ...
    xxxPATHS="/tmp /usr/tmp ...
    $ sed "s/PRUNE/\"$pattern\"/" /etc/updatedb.conf
    "xxx"FS="sysfs selinuxfs ...
    "xxx"PATHS="/tmp /usr/tmp ...
    

    라인주소: 특정 라인만 편집
    $ sed -e '1d' /etc/services | more

    라인범위주소: 두 개의 주소를 콤마로 구별하면 sed는 첫 번째 주소부터 두 번째 주소까지 명령어를 적용한다.
    $ sed -e '1,10d' /etc/services | more

    정규식주소: 라인이 정규식과 매치되면 편집, 슬래쉬(/) 사용
    $ sed -e '/^#/d' /etc/services | more

    반복되는 공백 제거
    $ sed 's/ \{2,\}/ /g'

    문자열의 앞뒤에 있는 공백만 제거
    $ sed -e 's/^ *//g' -e 's/ *$//g'

    정규표현식
    $ sed -n -e '/BEGIN/,/END/p' /my/test/file | more
    정규식 범위주소: 두 개의 정규식을 콤마로 분리
    sed 는 첫 번째 정규식을 찾는 첫 번째 라인부터 시작하여, 두 번째 정규식을 찾는 라인을 포함할 때까지 모든 라인들을 찾을 것이다. BEGIN 을 찾지 못하면 어떤 데이터도 프린트되지 않는다. BEGIN은 찾았지만, END를 찾지 못했다면 모든 라인들은 프린트되지 않는다.

    sed 's_^.*\(smp\|hugemem\|PAE\)$_-\1_;t;s_.*__;'
    echo $PWD | sed -n 's:^\(/.*\)\(/[^/]*/[^/]*/[^/]*$\):\\.\.\2:p;t;p'
    
    http://unix.derkeiler.com/Newsgroups/comp.unix.questions/2005-04/0130.html

    - t: sed 의 "test" command 이다.
    substitution 이 이전에 일어났다면, 스크립트 끝으로 점프한다.
    pattern space 에 다음 라인을 쓴다.
    사이에 모든 명령을 생략한다.
    만약 실패한다면 라인을 다음 명령에 전달한다.

    - p: 명령은 pattern space 에 변경되지 않은 콘텐츠를 출력한다.
    만약 "t foo" 처럼 t 명령에 라벨을 붙이면,
    ":foo" 로 점프하고 그 지점부터 명령을 실행한다.
    관련된 sed 명령은 "branch" 에 대한 "b" 이다.

    b: test 는 안하지만 나머지는 비슷하다.
    그래서 label _before_ 과 함께 자주 루프를 셋팅하는데 사용된다.

    인풋스트림은 물론 표준 입력 내지는 파일입력이다.
    인풋스트림이 패턴스페이스에 올라갈 때는 1라인씩 끊어서 올라간다.
    패턴스페이스에 들어간 스트림은 sed명령어를 이용해 수정할 수 있다.
    홀드버퍼는 패턴스페이스에 들어간 스트림 중 차후에 사용하려는 부분을 임시로 저장할 수 있다.
    h, g, x 등의 명령을 쓰면 홀드버퍼에 내용을 쓰거나 홀드버퍼로부터 내용을 가져올 수 있다.
    마지막으로, sed 명령을 모두 수행하면 패턴스페이스의 내용을 아웃풋스트림으로 출력한다.

    SED명령어들
    SED를 사용하기 위해서 익혀야할 것은 패턴스페이스 위에 올려진 한 줄을 요리하기 위한 명령어다.
    = : 현재 줄 번호를 출력한다.
    b label : 이 명령어로 지정한 label로 이동한다(점프한다). label 이 명시되지 않으면 맨 끝으로 이동한다(패턴스페이스에서 할 일은 끝났고 아웃풋스트림으로 출력)
    d: 현재 패턴스페이스 위에 올라온 내용을 지운 뒤 다음 줄을 읽어서 패턴스페이스에 올린다. 그리고 맨 처음 명령어로 돌아간다.
       cycle? sed 은 라인단위 작업이지만,  d 처럼 사이클이면 전체 라인을 작업한다.
       sed 'G;h' <파일>  sed '/regexp/d;G;h' <파일>
       전자는 1 line 단위로 G;h 실행한다.
       후자는 /regexp/d <파일> 하고나서, 라인단위로 G;h 실행한다.
    D: 패턴스페이스 위에 올라온 내용 중 첫번째 newline 캐릭터까지만 지운다. 만약 패턴스페이스에 내용이 남아있다면 다음 줄을 읽는 것은 건너뛴다. 그리고 맨 처음 명령어로 돌아간다.
    g: 홀드 버퍼에 있는 내용을 패턴스페이스에 덮어쓴다
    G : 홀드 버퍼에 있는 내용을 패턴스페이스의 맨 뒤에 붙인다.
    h : 패턴스페이스의 내용을 홀드버퍼에 덮어쓴다.
    H : 패턴스페이스의 내용을 홀드버퍼의 맨 뒤에 붙인다.
    n : 패턴스페이스의 내용을 출력하고 패턴스페이스를 비운 뒤 다음 줄을 읽는다
    N: 다음 줄을 현재 패턴스페이스의 맨 뒤에 붙인다
    p : 현재 패턴스페이스 전체를 출력한다
    P : 현재 패턴스페이스 중 첫번째 newline캐릭터까지 출력한다
    q :  즉각 sed 를 종료한다. 단 auto-print 기능이 꺼져있지 않다면 현재 패턴스페이스를 출력한 뒤 종료한다.
    Q: auto-print 기능과 상관 없이 더 이상의 프로세스를 수행하지 않고 즉각 sed를 종료한다.
     s/regex/repl/ 
    regex 를 repl 로 변경한다. 찾아바꾸기 기능이라고 생각하면 된다.
    repl 에 있는 & 는 pattern space 에서 매칭된 부분 전체를 말한다.
    \1 ~ \9 는 regex 의 \(...\) 그룹을 순서대로 말한다.
    t label : s/// 명령어가 성공했을 경우(regex가 repl로 바뀌면) label로 점프한다. 아무 것도 정해지지 않으면 (label이 명시되지 않으면 맨뒤로 점프한다)
    T label : s/// 명령어가 성공하지 않을 경우 label로 점프한다.(label이 명시되지 않으면 맨 뒤로 점프한다)
    x : 홀드버퍼의 내용과 패턴스페이스 내용을 맞바꾼다.
    r filename: 파일에서 읽은 내용을 통째로 패턴스페이스 뒤에 붙인다
    R filename: 파일에서 읽은 한 줄을 패턴스페이스 뒤에 붙인다. 또 이 명령이 실행되면 그 다음 줄을 읽는다.
    w filename: 현재 패턴스페이스의 내용을 파일에 쓴다.
    W filename: 현재 패턴스페이스 내용 중 newline 캐릭터까지 파일에 쓴다.

    명령행 옵션
    -e script: script 를 실행한다. -e를 쓰지 않아도 되지만 가독성을 높이기 위해 여러 개의 -e 'script' -e 'script1'... 쓰는 게 좋다.
    -f script-file: 스크립트 파일 내용을 더해서 실행한다.
    -i : 파일을 수정한다, suffix 가 있으면 <파일이름> 로 백업한다. -i 가 없으면 파일은 수정하지 않고 출력만 한다
    -n: auto-print 기능을 끈다. 즉 p 명령어로 출력하는 경우에만 출력한다.
    -r : 확장된 정규표현식을 사용한다. 예를 들어 \(\) 이런식으로 쓸 필요 없이 () 이렇게 쓸 수 있다.
    $ sed -i "/PRUNEFS/d" ./updatedb.conf
    $ ls updatedb* 
    updatedb.conf
    $ sed -i.org "/PRUNEFS/d" ./updatedb.conf
    $ ls updatedb*
    updatedb.conf  updatedb.conf.org
    

    reverse unmount
    http://www.catonmat.net/blog/sed-one-liners-explained-part-one/
    $ awk '$3 ~ /sanique3/ { print $1, $2, $3 }' /etc/mnttab | sed '1!G;h;$!d'
    /dev/cvm/dsk/lv4 /mnt/cfm4 sanique3
    /dev/cvm/dsk/lv3 /mnt/cfm3 sanique3
    /dev/cvm/dsk/lv2 /mnt/cfm2 sanique3
    /dev/cvm/dsk/lv1 /mnt/cfm1 sanique3
    

    Reverse order of lines (emulate “tac” Unix command)
    $ sed '1!G;h;$!d'
    
    1 라인번호
    G append hold space to pattern space
    1!G => 첫번째 줄만 G 실행하지 말아라,
    비어있는 hold space 를 pattern space 에 넣으면 빈데이타를 카피해서 빈줄이 생긴다.
    그래서 첫번째 줄은 G 명령 실행하지 않는다.
    hold space 에 있는 cfm1 을 pattern space 에 있는 cfm2 뒤에 복사해서 cfm2 뒤에 cfm1 따르는 순서가 된다. 역순이 된다.
    h copy pattern space to hold space
    pattern space 에 있는 cfm1 을 hold space 에 복사한다.
    pattern space 에 있는 cfm2/cfm1 을 hold space 에 복사한다
    d Delete pattern space.  Start next cycle.
    pattern space 를 지운다.
    $ 라인의 끝, 한줄끝. 마지막 줄
    $!d => 마지막 줄만 d 실행하지 말아라.
    모든 명령을 마쳤으므로 auto-print 기능 때문에 패턴스페이스의 전체 내용이 출력된다.

    $ sed '/^$/d;G' 
    /^$/ 정규식을 매칭하는 어드레스면 d 명령을 실행한다.
    d는 현재 패턴스페이스 내용을 지운 후 다시 sed 스크립트의 맨 처음 부분으로 돌아간다.
    즉 또 다시 /^$/를 매칭하는지 검사한다.
    또 매칭하면 지운다.
    이렇게 반복하다가 /^$/에 매칭되지 않으면 G를 실행하게 된다.
    G는 홀드버퍼에 있는 내용을 패턴스페이스 뒤에 붙이는 명령어다.
    이 경우 홀드버퍼에 아무 내용도 없으므로 그냥 빈행이 이어붙여지는 셈이다.
    정리하자면 빈행은 모두 지우고 빈행이 아닌 행 다음에 빈행을 한 줄 추가한다.

    Reverse a line (emulates “rev” Unix command)
    $ sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'  
    http://groups.google.com/group/comp.unix.shell/browse_frm/thread/b3885f5692585f64?tvc=1
    /\n/!G  => /정규표현식/G,input stream 이 빈행이면 G 실행하지 않는다. 비어있는 hold buffer 한 줄로 추가하니까 결국에는 한행마다 뉴라인을 추가한다.

    s/\(.\)\(.*\n\)/&\2\1/ 
    첫번째 캐릭터를 \1로 그루핑, 나머지 모든 것을 \2로 그루핑.
    & 는 regexp 로 매칭된 전체를 말함.
    pattern space 에 1234 가 있으면 & 로 구한 1234 뒤에 2번 그룹 234 뒤에 1번 그룹 1 이 뒤따른다.

    //D => /정규표현식/D, pattern 이 비어있으면 직전에 사용한 regexp 을 말한다.
    /\(.\)\(.*\n\)/D 과 같다.
    D 는 pattern space 에서 처음부터 첫번째 뉴라인까지 삭제한다.
    $ s/love/**&**/ 
    love will become **love**. 
    

Designed by Tistory.