-
sedbin/script 2008. 3. 19. 14:37sed 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**.