데이터 엔지니어링을 하다보면, 문자열 파싱을 이용해야할 때가 많다.
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 로 치환하는 것
'엔지니어링' 카테고리의 다른 글
같은 스키마를 가진 파일들 안에서 여러개의 Athena 테이블이 만들어질 때 (0) | 2022.05.17 |
---|---|
리눅스 grep 명령어 (0) | 2022.05.04 |
아테나(Athena)의 데이터베이스와 Glue Data Catalog 데이터베이스의 차이 (0) | 2022.05.04 |
파일 시스템 알아보기 (0) | 2022.04.15 |
Python class 변수 , 인스턴스 변수 (0) | 2022.04.05 |