SED(Stream Editor)

SED는 Stream Editor의 약자로 sed라는 명령어로 원본 텍스트 파일을 편집하는 유용한 명령어입니다. 리눅스의 editor라하면 생각나는 에디터가 있지 않나요? vi 편집기가 대표적인데, 여러분들이 vi편집기로 편집할때는 vi filename의 명령을 이용해서 파일을 열고 난 이후에 각종 vi 명령어를 통해서 이리 저리 움직여 추가, 삭제, 변경 등의 편집을 하게 되죠. 그리고 작업이 다 끝나게 되면 저장 후 나가게 됩니다. 이때 여러분은 원래의 파일을 변경하여 저장하기 때문에 원본은 변경됩니다. 그리고 vi는 실시간 저장할 수가 있습니다. 여기서 sed는 vi 편집기와는 다르게 이런 차이점이 있습니다.

 

1. sed와 vi가 다른 점은 sed는 명령어 형태로 편집이 되며 vi처럼 실시간 편집이 아닙니다.

2. 원본을 건드리지 않고 편집하기 때문에 작업이 완료되었어도 기본적으로 원본에는 전혀 영향이 없다는 점입니다.(단, 여러분이 sed옵션에서 -i 옵션을 지정한다면 원본을 바꾸게 됩니다.) 그래서 내부적으로 특수한 저장 공간인 버퍼를 사용합니다. 두 가지 버퍼는 패턴 버퍼(패턴 스페이스라고도 합니다)와 홀드 버퍼(홀드 스페이스라고도 합니다)입니다.

 

아래의 그림을 보면 sed는 InputStream으로 파일의 내용을 가져옵니다. 그리고 난 후에 패턴 버퍼에 그 내용을 담고 있으며 데이터의 변형과 추가를 위해 다시 임시 버퍼를 사용하게 되는데, 그게 홀드 버퍼입니다. 그리고 작업이 전부 완료되었다면 패턴 버퍼에 그 내용이 담기는데, 그 내용을 OutputStream으로 보내주게 되면 비로소 우리가 원하는 결과가 출력되는겁니다. 기본적으로 OutputStream은 콜솔화면인 stdout입니다. 우리는 그냥 sed가 내부적으로 2개의 버퍼를 가지고 있다고 보시면 됩니다. 

pattern space and hold space

 

 

이제 sed의 기본적인 개념을 알아보았으니 사용법에 대해서 알아보아야겠죠? 그 전에 sed에 대한 input 파일은 아래의 내용처럼 간단한 텍스트 파일로 하도록 하겠습니다. 필요에 따라 다른 text파일도 사용하도록 하겠습니다.

 

sed_test_file.txt

name    phone           birth           sex     score
reakwon 010-1234-1234   1981-01-01      M       100
sim     010-4321-4321   1999-09-09      F       88
nara    010-1010-2020   1993-12-12      M       20
yut     010-2323-2323   1988-10-10      F       59
kim     010-1234-4321   1977-07-17      M       69
nam     010-4321-7890   1996-06-20      M       75
sol     010-5911-1111   1976-10-12      F       60
lee     010-4949-4949   1988-09-30      F       80
feng    010-1111-9999   1979-03-20      M       90

 

기본적으로 sed는 아래와 같은 형태로 사용합니다. 

sed -n -e 'command' [input file]

 

 

-n : sed는 pattern buffer의 내용을 자동적으로 출력해주는데, 이 옵션을 사용하게 되면 자동 출력을 하지 않습니다. -n옵션을 하지 않고 sed명령을 해보시면 눈에 띄게 많은 데이터가 출력되는것을 확인할 수 있습니다. 매우 지저분하지요. 그래서 -n옵션을 붙여 패턴 버퍼의 자동출력을 하지 않습니다. 여러분은 그래서 sed 명령의 기본 형태는 sed -n으로 생각하시면 됩니다.

 

-e : 이 옵션 다음으로는 우리가 사용할 command를 가지고 텍스트 파일을 가공해줍니다. -e의 command에는 어떤 종류가 있는지 확인해보도록 합시다.

그리고 맨 마지막에는 우리가 가공할 원본 파일을 지정해주면 됩니다. 

1. 특정 행을 출력 - p (print)

1-1. 천재 내용을 출력 : 기본적으로 전체의 줄을 출력하려면 command에 /$/p 또는 1,$p로 출력해볼 수 있습니다. 

sed -n -e '1,$p' sed_test_file.txt
sed -n -e '/$/p' sed_test_file.txt

 

1-2. 첫번째 줄 출력 : 여러분이 첫번째 줄만 출력해주기를 아래의 command를 사용할 수 있습니다. 

 sed -n -e '1p' ./sed_test_file.txt
name    phone           birth           sex     score

 

pprint의 p를 의미합니다. 

1-3. start ~ end 줄까지 출력 : 그렇다면 첫째줄부터 4번째줄을 출력하기를 원한다면 쉼표로 구분된 출력하길 원하는 줄, 마지막 줄 p 의 형태를 사용하면 됩니다.

sed -n -e '1,4p' sed_test_file.txt
name    phone           birth           sex     score
reakwon 010-1234-1234   1981-01-01      M       100
sim     010-4321-4321   1999-09-09      F       88
nara    010-1010-2020   1993-12-12      M       20

 

1-4. 특정줄에서 마지막 줄까지 출력 : 어떤 줄에서 마지막 줄까지 출력하려면 $문자를 사용하면 됩니다. $는 마지막줄을 의미합니다. 그래서 5번째 줄에서 마지막줄까지 출력하려면 아래와 같은 command를 사용할 수 있습니다.

sed -n -e '7,$p' sed_test_file.txt
nam     010-4321-7890   1996-06-20      M       75
sol     010-5911-1111   1976-10-12      F       60
lee     010-4949-4949   1988-09-30      F       80
feng    010-1111-9999   1979-03-20      M       90

 

1-5. 다중 command 사용 : 만약 command를 여러개 사용하고 싶다면 -e 옵션을 이용해서 여러개 사용하여 command를 줄 수 있습니다. 만약 1번째 줄을 출력해주고, 8번째 줄부터 끝까지 출력하기를 원한다면 아래의 명령을 사용하면 됩니다.

sed -n -e '1p' -e '8,$p'  sed_test_file.txt
name    phone           birth           sex     score
sol     010-5911-1111   1976-10-12      F       60
lee     010-4949-4949   1988-09-30      F       80
feng    010-1111-9999   1979-03-20      M       90

 

1-6. 특정 문자열이 있는 줄 출력

만약 위의 파일에서 여자(F, Female)만 출력한다고 하다면 어떻게 command를 어떻게 사용할까요? 아래와 같은 형식대로 사용하면 됩니다.

/포함된 문자열/p

 

텍스트 파일에서 우리가 찾을 문자열이 포함된 줄을 출력(p, print)한다고 생각하시면 됩니다. 아래의 명령이 여성만 뽑아내는 command입니다.

sed -n -e '/F/p'  sed_test_file.txt

 

2. 특정 행 삭제 - d (delete)

행삭제에 관한 명령어d를 사용하면 됩니다. d를 사용하는 것외에는 위의 줄 출력을 해주는 명령어 형태로 사용하면 됩니다. 

2-1. 2~6번째 줄을 삭제하고 나머지 모든 내용을 출력

sed -n -e '2,6d' -e '1,$p'  sed_test_file.txt
name    phone           birth           sex     score
nam     010-4321-7890   1996-06-20      M       75
sol     010-5911-1111   1976-10-12      F       60
lee     010-4949-4949   1988-09-30      F       80
feng    010-1111-9999   1979-03-20      M       90

 

3. 단어 치환(Substitute) - s (substitute)

이제부터는 출력결과는 생략하도록 하겠습니다. 특정 단어를 치환하려면 s명령을 이용하면 됩니다. 형식은 아래와 같습니다. 

3.1 기본적인 특정 단어 치환

s/old/new/g
s/old/new/gi

 

단어 s substitute(치환)의 약자, 그리고 /로 구분하여 old는 단어를 치환할 문자열, new는 새롭게 치환한 문자열인데 비어있으면 그 문자열을 삭제한 효과를 가질 수 있습니다. gglobal의 약자로 전체에 적용됨을 의미합니다. 

두번째의 i는 ignore case의 약자로 old의 단어를 검색할때 대소문자 구분하지 않겠다는 것을 의미합니다. 

아래 명령의 결과를 보고 차이점을 확인해보세요.

sed -n -e 's/reakwon/reak/g' -e '2p' sed_test_file.txt
sed -n -e 's/reakwoN/reak/g' -e '2p' sed_test_file.txt
sed -n -e 's/reakwoN/reak/gi' -e '2p' sed_test_file.txt

 

3.2 특정 단어로 시작 혹은 끝나는 단어를 포함하는 라인의 문자열 치환

특정단어로 시작하는 단어로 문자열을 치환하는 것도 가능합니다. 특정 단어로 시작하는 줄을 선택하려면 앞에 '^'문자를 사용하면 되죠. 사실 정규표현식을 아신다면 앞에 ^가 붙는다면 ^이후에 나오는 문자열로 시작되는 문자열들을 추출한다는 것을 아실겁니다. 사실 몰라도 외워서 아시면 됩니다. 단 많이 실수하시는 부분이 특정 단어로 시작하거나 끝나는 문자열이 아닌 줄(line)입니다.

 

아래의 파일(let_it_go.txt)에서 Let으로 시작하는 줄의 첫 Let를 LET으로 바꿔보려면 다음 보이는 명령을 사용하면 됩니다.

Let it go, let it go.
Can't hold it back anymore.
Let it go, let it go.
Turn away and slam the door.
I don't care what they're going to say.
Let the storm rage on.
The cold never bothered me anyway.

 

sed -n -e 's/^let/LET/gi' -e '1,$p' let_it_go.txt

 

반대로 끝나는 문자열은 끝에 $를 붙여줘서 검색하면 됩니다. Anyway. 으로 끝나는 줄의 Anyway를 대문자로 바꾸려면 아래와 같은 command를 사용하면 됩니다.

sed -n -e 's/anyway.$/ANYWAY/gi' -e '1,$p' let_it_go.txt

 

4. 문자열 추가 - a, i (append, insert)

문자열을 추가하는 방법에는 두 가지 정도가 존재합니다. 해당 문자열 아래에 추가하느냐(Append) 아니면 이 전 줄에 삽입하느냐(Insert)가 있는데요. 기본적인 형식은 아래의 command처럼 사용합니다.

/찾을 문자열/a\다음 출에 추가할 문자열
/찾을 문자열/i\위에 삽입할 문자열

 

찾을 문자열 뒤에 추가할 문자열을 위의 형식대로 사용하면 됩니다. 위의 let_it_go.txt파일에서 bye로 끝나는 줄 다음에 end라는 줄을 넣고 싶다면 이렇게 사용하면 됩니다. 반대로 위에 추가하려면 a를 i로 바꾸면 되겠죠.

 

 

sed -n -e '/bye/a\end' -e '1,$p' let_it_go.txt

 

5. 특정 행의 내용을 전부 교체 - c (change)

c command를 이용해서 행의 내용을 바꿀 수 있습니다. command 형태는 이렇습니다.

/바꿀 행이 포함한 문자열/c\바꿀 행의 내용

 

예를 들어 Let으로 시작하는 줄의 내용을 바꾸고 싶다면 어떻게 할까요? 우선 ^를 사용하여 Let으로 시작하는 줄들을 찾고 c 커맨드로 바꿔질 줄 내용을 입력해주시면 됩니다.

sed -n -e '/^Let/c\Let it go X2' -e '1,$p' let_it_go.txt

 

6. 특정 행에 파일의 내용을 추가 - r (read)

혹은 파일의 내용을 줄에다가 추가할 수도 있습니다. 여기 우리가 내용을 추가할 파일이 존재합니다.

 

perfect.txt

PERFECT! EXCELLENT!

 

100으로 끝나는 줄에 저 텍스트 파일의 내용을 아랫줄에 첨가하려면 아래와 같은 명령을 사용하면 됩니다.

 sed -n -e '/100$/r perfect.txt' -e '1,$p' sed_test_file.txt
name    phone           birth           sex     score
reakwon 010-1234-1234   1981-01-01      M       100
PERFECT! EXCELLENT!
sim     010-4321-4321   1999-09-09      F       88
nara    010-1010-2020   1993-12-12      M       20
yut     010-2323-2323   1988-10-10      F       59
kim     010-1234-4321   1977-07-17      M       69
nam     010-4321-7890   1996-06-20      M       75
sol     010-5911-1111   1976-10-12      F       60
lee     010-4949-4949   1988-09-30      F       80
feng    010-1111-9999   1979-03-20      M       90

 

이상으로 sed에 대한 기본 개념과 사용방법, 그리고 예제를 살펴보았습니다. 여러분이 정규표현식을 사용하여 깊게 사용할 수도 있지만, 저는 정규표현식을 거의 사용할 일이 없으니 여기까지 하도록 하겠습니다. 이정도만 알아도 sed 명령을 사용하는 것에는 불편함이 없을 겁니다.

 

 

반응형
블로그 이미지

REAKWON

와나진짜

,