Sed
Stream EDiter 의 약자
출처
- 원본 아래 내용은 개인용으로 정리한 내용 입니다.
s 커맨드
echo day > old
# sed script sourcefile > destfile
sed s/day/night/ old > new
echo day | sed s/day/night/
# night
'' 를 쓰는걸 추천
상황에 따라 써도 안써도 되지만 홑따움표를 쓰는걸 추천한다. Detail About Quote
echo day | sed 's/day/night/'
# night
정확이 명시한것만 치환 나머지는 그냥 출력
echo Sunday | sed 's/day/night/'
# Sunnight
Sed는 라인 단위로 동작한다.
- 특정 신호를 주지 않으면 기본은 맨앞에꺼 한개 치환
test.txt
one two three, one tow three
for three two one
one hundrad
sed 's/one/ONE/' < test.txt
# ONE two three, one two three
# for three two ONE
# ONE hundrad
s 커맨드 문법
문자열에서 특정 패턴을 찾아 그 부분만 변환 문자열로 변환 (없으면 유지)
symbol | desc |
---|---|
s | 치환 명령어 |
/../../ | 경계기호 delimit (de-'down'm limitara-'limit'') |
one | 찾을 정규식 패턴 |
ONE | 변환 될 스트링 |
경계기호 슬래시에 대해서
슬래시를 경계 기호로 쓰기 때문에 패턴 자체에 슬래시가 있으면 이스케이프 문자를 통해 치환 해주어야 한다.
"\" 하지만 보기 나쁨으로 다른 경계기호를 사용하기도 한다. "_", ":", "|"
echo /home/a > old
sed 's/\/home\/a/\/newhome\/b/' old
sed 's_/home/a_/newhome/b_' old
sed 's:/home/a:/newhome/b:' old
sed 's|/home/a|/newhome/b|' old
매칭 스트링을 표기하기 위해 & 을 사용
매칭되는 스트링을 유지한채 특정 패턴을 더하고 싶을 경우가 있다. 예를 들어 abc 를 (abc) 로 바꾸고 싶다.
echo "abc" > old
sed 's/abc/(abc)/' old
# (abc)
하지만 정확한 패턴을 모른다면 & 으로 사용 할 수 있다.
echo "abc" > old
sed 's/[a-z]*/(&)/' old
# (abc)
& 을 몇번이고 쓸수 있다.
echo "123 abc" > old
sed 's/[0-9]*/& &/' old
새드의 첫번째로 매치하는 패턴을 찾고, 그것에 대해 탐욕적(최대한 매칭 시킬려고 한다.)으로 하려고 한다.
아래와 같은 경우 * 을 사용해 제로 또는 많은을 찾으려고 한다.
아래의 [0-9]*
은 0또는 많은 숫자를 찾을려고 하기 때문에 라인의 첫번째 빈공간에 매칭된다(0개의 숫자로 매칭됨)
인풋이 abc 123 일 경우 output은 맨앞의 공간에 빈@빈 == @
을 추가한다.
echo "abc 123 efg" > old
sed 's/[0-9]*/&@&/' old
# @abc 123 efg
아래와 같이 하면 숫자가 최소 1개 있어야 함으로 123 에 매칭된다. * 은 앞에 표현된 표현식을 매칭시킨다. \, ., a bracket expression 은 매칭되지 않는다.
echo "abc 123 efg" > old
sed 's/[0-9][0-9]*/& &/' old
# abc 123 123 efg
확장 정규 표현형
세드에서 +는 기본적으로 문자열이다. 1개 또는 더를 의미하는 기호로 + 를 사용하려면 새드에 확장 정규형을 사용한다고 명시해 주어야 한다. (mac 은 -E 를 사용)
echo "abc 123 efg" > old
sed -E 's/[0-9]+/& &/' old
# abc 123 123 efg
\1을 이용해 부분 문자열 사용방법
\(regex\)
탈출된 가로를 사용하면 문자열의 일부를 추출해서 메모리에 저장해둔다.
결과에서 \1, \2, ..\9 까지 사용 할 수 있다.
- 첫번째 단어만 유지 (나머지는 지움)
- 정규식은 최대한 탐욕적으로 매칭할려고 노력한다.
echo "abc 123 efg" > old
sed 's/\([a-z]*\).*/\1/' old
- 두단어 치환
echo "abc efg" > old
sed 's/\([a-z]*\) \([a-z]*\)/\2 \1/' old
- 만약 한글자만 있거나 뒤에 라인이 없으면 검색 패턴을 만족 못함으로 아무것도 안한다.
- 스페이스만 있으면 * 이기때문에 만족한다.
echo "abc" > old
sed 's/\([a-z]*\) \([a-z]*\)/\2 \1/' old
- 한단어 이상일때만 치환
-E
를 사용하면 탈출 괄호를 사용하지 않는다.
echo "abc d" > old
sed 's/\([a-z][a-z]*\) \([a-z][a-z]*\)/\2 \1/' old
sed -E 's/([a-z]+) ([a-z]+)/\2 \1/' old
- 패턴에서도 \1 을 사용 할 수 있다.
- 중복 단어를 없애고 싶다.
echo "abc abc" > old
sed 's/\([a-z]*\) \1/\1/' old
- 중복 단어가 있는 줄만 출력하고 싶다면
echo "abc abc" > old
sed -n '/\([a-z][a-z]*\) \1/p' old
sed -En '/([a-z]+) \1/p' old
- 앞 3글자 역순으로
echo "abc abc" > old
sed 's/\(.\)\(.\)\(.\)/\3\2\1/' old
Sed Pattern flags
대부분의 유닉스 명령어는 파일 단위로 동작하며 라인을 한줄씩 읽은 후 처리한다.
/g global 변경
변경 할 경우 디폴트는 제일 첫번째 나오는 단어만 변경이다. g 를 주면 라인에서 매칭되는 모든 패턴을 변경한다.
- 모든 단어에 ()를 치고 싶다면
echo "abc abc" > old
sed 's/[^ ]*/(&)/g' old
Sed의 작동 순서
들어오는 데이터에만 동작함. 라인을 읽다가 패턴이 매칭되면 변경하고 남은 라인을 읽음. 변경된 라인을 다시 읽지 않음
echo "abc efg" > old
sed 's/abc/abc abc/g' old
/1, 2 매칭 패턴 지정
플래그가 없다면 첫번째 매칭 패턴만 바뀐다. g 가 있다면 모든 매칭 패턴이 바뀐다.
- 두번째 단어를 없애보자.
echo "abc efg" > old
sed 's/\([a-zA-Z]*\) \([a-zA-Z]*\)/\1 /' old
- 플래그에 숫자를 쓰면 그 패턴만 변경된다.
- 두번째 단어 없애기
echo "abc efg hij " > old
sed 's/[a-zA-Z]* //2' old
- password 에서 2번째 지우기
echo "_fpsd:*:265:265:FPS Daemon:/var/db/fpsd:/usr/bin/false" > old
sed 's/[^:]*:/@:/2' old
/p print
새드는 기본적으로 모든 라인을 출력하고 변환된 라인이 있으면 변환된 라인을 출력한다. -n 을 주면 아무것도 출력하지 않는다. /p 를 주면 변경된 라인을 출력하게 한다.
echo "line1 \n abc efg hij \n line3" > old
sed -n 's/abc/@/p' old