본문 바로가기
엔지니어링

리눅스 SED 명령어

by 당나귀🐴 2022. 5. 4.
데이터 엔지니어링을 하다보면, 문자열 파싱을 이용해야할 때가 많다.

Java 나 Python 을 이용할 수도 있지만 해당 언어가 설치되지 않은 인스턴스일 수 있다.

리눅스 기반의 인스턴스를 많이 이용하다보니 쉘 명령어로 작동하는 sed 라는 프로그램을 이용하면 텍스트 파일의 문자를 변경하는데 많은 도움을 준다.

 

SED 란? (Streamlined EDitor)


  • sed 도 프로그램이다. 문자열을 다루는 프로그램이다.
  • 문자열을 찾거나, 치환하기 위해 사용한다.
  • 텍스트 에디터를 사용해도 되지만 sed 도구를 통해 쉘 스크립트나 명령을 통해 문자열 작업을 진행할 수 있다.

 

SED 작동방식


(1) input 파일을 한 라인당 한번에 읽습니다.

(2) 각 라인은 패턴 스페이스(Pattern Space)라는 버퍼에 복사됩니다.

(3) Command 가 패턴 스페이스에 저장된 라인 별로 실행됩니다.

(4) 작동 후에 패턴 스페이스가 지워집니다.

(5) 새로운 파일이 들어오면 (1) 부터 반복합니다.

 

sed [option] ‘address action’ INPUTFILE(s)

 

예시로 사용될 텍스트 문장 cat -n sample.text (라인 넘버도 같이 출력)

1 Knox in box.
2 Fox in socks.
3
4 Knox on fox in socks in box.
5
6 Socks on Knox and Knox in box.
7 Fox in socks on box on Knox.

[option]

  • -n : 패턴 스페이스에 있는 내용을 출력
  • -i : 입력된 파일을 수정
  • -f : 변환 스크립트를 파일로 추가
  • -e : 변환 스크립트를 커맨드에 입력으로 추가 (여러개의 편집 명령을 사용할 때)

‘address action’

  • address 는 Line address, Context address 두 가지로 나뉘어짐

 

Line address 예시 : 라인 넘버와 관련된 내용


sed -n '2p' sample.text : 2 라인 출력

2  Fox in socks.

sed -n '4,7p' sample.text : 4~7 라인 출력

4  Knox on fox in socks in box.
5
6  Socks on Knox and Knox in box.
7  Fox in socks on box on Knox.

sed -n '$p' sample.text : $ 는 마지막 라인만 출력

7  Fox in socks on box on Knox.

sed -n -e '$p' -e '4,7p' sample.text

  • -e 는 두개 이상의 명령어를 사용할 떄 사용한다.
  • 마지막 줄과 4~7 라인을 출력하는 것
  • sed 는 라인별로 실행하는 것이기 때문에 4~7 라인이 먼저 출력되고 마지막라인인 7 라인이 한번 더 출력된다.
4  Knox on fox in socks in box.
5
6  Socks on Knox and Knox in box.
7  Fox in socks on box on Knox.
7  Fox in socks on box on Knox.

Context address : 라인 넘버 대신에 패턴을 사용하는 방식


/p 특정 단어를 포함한 행 출력

sed -n '/Knox/p' sample.text : Knox 를 포함한 행 출력

1  Knox in box.
4  Knox on fox in socks in box.
6  Socks on Knox and Knox in box.
7  Fox in socks on box on Knox.

sed -n '/^Knox/p' sample.text : Knox 로 시작하는 행 출력

1  Knox in box.
2  Knox on fox in socks in box.

sed ‘s/old_string/new_string/’ filename : old_string 을 new_string 으로 변경하는 것

  • 한 라인당 한번만 실행됨
  • 한 라인에서 여러번 실행하려면 g 패턴 추가
  • 횟 수를 지정할 수도 있음

sed 's/Knox/Cnox/' sample.text

  • 한 라인에서 한번만 변경되기 때문에 6번 라인에 Knox 가 Cnox 로 변경되지 않은 것을 확인할 수 있다.
1  Cnox in box.
2  Fox in socks.
3
4  Cnox on fox in socks in box.
5
6  Socks on **Cnox and Knox** in box.
7  Fox in socks on box on Cnox.

sed 's/Knox/Cnox/g' sample.text

1  Cnox in box.
2  Fox in socks.
3
4  Cnox on fox in socks in box.
5
6  Socks on Cnox and Cnox in box.
7  Fox in socks on box on Cnox.

sed ‘s/Knox/Cnox/1’ sample.text : 라인당 한번만 변경 실행

1  Cnox in box.
2  Fox in socks.
3
4  Cnox on fox in socks in box.
5
6  Socks on Cnox and Knox in box.
7  Fox in socks on box on Cnox.

sed 's/Knox/Cnox/2' sample.text : 라인당 두번만 변경 실행

1  Knox in box.
2  Fox in socks.
3
4  Knox on fox in socks in box.
5
6  Socks on Knox and Cnox in box.
7  Fox in socks on box on Knox.

sed 는 전체 문장을 대상으로 출력되기 때문에, 내가 타겟을 변경한 내용 (패턴 스페이스의 내용)을 출력하고 싶다면 -n 과 p 패턴을 같이 사용한다.

sed -n 's/Knox/Cnox/2p' sample.text : Knox 가 두번 반복되는 행을 Cnox 로 바꿔서 해당 행만 출력

6 Socks on Knox and Cnox in box.

패턴 i 는 대소분자를 구분하지 않는다

sed 's/fox/cow/' sample.text : 2번째 줄의 Fox 는 대문자이기 때문에 변경되지 않았다.

1  Knox in box.
2  Fox in socks.
3
4  Knox on cow in socks in box.
5
6  Socks on Knox and Knox in box.
7  Fox in socks on box on Knox.

sed 's/fox/cow/i' sample.text : 대문자를 무시(ignore) 하고, Fox 를 cow 로 변경한다.

1  Knox in box.
2  cow in socks.
3
4  Knox on cow in socks in box.
5
6  Socks on Knox and Knox in box.
7  cow in socks on box on Knox.

특정 라인을 지정할 수도 있다.

sed -n '4 s/knox/Cnox/ip' sample.text : 4번라인의 knox(Knox) 를 Crox 로 변경한다.

4 Cnox on fox in socks in box.

sed -n '4,6 s/knox/Cnox/igp' sample.text : 4번부터 6번 라인까지의 knox(Knox)를 모두 Crox 로 변경한다.

4 Cnox on fox in socks in box.
6 Socks on Cnox and Cnox in box.

특정 라인을 삭제할 수도 있다.

sed '2d' sample.text : 2번 라인을 삭제한다

1  Knox in box.
2
3  Knox on fox in socks in box.
4
5  Socks on Knox and Knox in box.
6  Fox in socks on box on Knox.

2번부터 마지막 라인까지 모두 삭제한다.

sed '2,$d' sample.text

1  Knox in box.

sed '/^$/d' sample.text : 빈 라인으로 이루어진 행삭제

1  Knox in box.
2  Fox in socks.
3  Knox on fox in socks in box.
5  Socks on Knox and Knox in box.
6  Fox in socks on box on Knox.

^ 는 행의 처음을 의미하고 $는 행의 끝을 의미하는 것

패턴을 좀 더 복잡하게 사용하는 것도 가능함

 

sed 's/[0-9][0-9]$/&.5/ file

  • [0-9][0-9] 는 두자리 숫자를 의미, $는 문장의 끝을 의미. 즉, 두 자리 숫자로된 단어
  • &는 검색된 문자열을 의미. &.5는 검색된 문자열에 .5 를 붙이는 의미
  • 예를 들어 10이란 단어를 찾으면 10.5 로 치환하는 것