Computer >> 컴퓨터 >  >> 스마트폰 >> Linux

리눅스 명령줄 마법 – sed로 파일 속 텍스트 한 번에 찾아 바꾸기

리눅스 명령줄 환경에서 작업하다 보면 하나 또는 여러 개의 파일 속 특정 문자열을 다른 내용으로 일괄 교체해야 하는 상황이 자주 발생합니다. 파일을 하나씩 열어 직접 수정하는 방법도 있지만, 대용량 파일이나 수십 개의 파일을 다뤄야 한다면 시간이 오래 걸리고 실수할 가능성도 커집니다. 다행히 리눅스에는 이런 작업을 자동화할 수 있는 강력한 도구가 이미 준비되어 있습니다.

sed – 강력한 스트림 편집기

이 글에서는 리눅스 기본 명령줄 도구인 sed(stream editor)를 사용해 파일 안의 문자열을 찾아 바꾸는 방법을 소개합니다. sed는 텍스트 변환과 치환에 특화된 매우 강력하고 유연한 도구로, 그 기능만 따로 책 한 권을 쓸 수 있을 정도입니다. 여기서는 그중 가장 널리 쓰이는 '찾기 및 바꾸기' 기능에 초점을 맞춥니다. 흥미가 생긴다면 정규 표현식과 함께 sed의 다른 기능들도 추가로 학습해 볼 것을 추천합니다.

기본 문법

파일 안의 문자열을 찾아 바꿀 때 사용하는 기본 문법은 다음과 같습니다.

# sed -i 's/[원래_문자열]/[새_문자열]/' filename.txt

실전 예제 – 데이터베이스 서버 IP 주소 변경하기

예를 들어 database.txt라는 파일에 데이터베이스 서버의 IP 주소가 여러 번 기록되어 있다고 가정해 봅시다. 새 데이터베이스 서버로 이전했고, 기존 IP 주소(192.168.1.16)를 새 주소(192.168.1.22)로 모두 업데이트해야 하는 상황입니다.

먼저 파일의 현재 내용을 확인합니다.

# cat database.txt
LOCAL_DATABASE = 192.168.1.16
LOCAL_DIR = /home/calvin/
PROD_DB = 192.168.1.16

이제 sed 명령으로 IP 주소를 일괄 교체합니다.

# sed -i 's/192.168.1.16/192.168.1.22/g' database.txt
# cat database.txt
LOCAL_DATABASE = 192.168.1.22
LOCAL_DIR = /home/calvin/
PROD_DB = 192.168.1.22

파일을 다시 열어보면 이전 IP 주소가 모두 새 주소로 바뀐 것을 확인할 수 있습니다.

명령어 구조 살펴보기

위 명령어를 하나씩 뜯어보면 다음과 같습니다.

  • sed : 스트림 편집기를 호출합니다.
  • -i : "in-place" 옵션으로, 결과를 화면에 출력하는 대신 원본 파일을 직접 수정합니다.
  • s : "substitute(치환)"의 약자로, 앞의 패턴을 뒤의 문자열로 바꾸라는 의미입니다.
  • g : "global(전역)"의 약자로, 각 줄에서 일치하는 모든 항목을 치환합니다.

s와 g 사이에 넣은 문자열이 치환 대상이 되며, 슬래시(/)로 구분된 이 구조는 정규 표현식(regex)을 활용한 다양한 패턴 매칭에도 그대로 적용됩니다.

g 옵션을 생략하면 어떻게 될까?

명령 끝의 g를 생략하면 치환이 '전역'이 아니게 됩니다. 즉, 각 줄에서 첫 번째로 일치하는 문자열만 교체됩니다. 한 줄에 동일한 텍스트가 여러 번 등장하는 경우 결과가 어떻게 달라지는지 직접 확인해 보겠습니다.

# cat database.txt
LOCAL_DATABASE = 192.168.1.16
LOCAL_DIR = /home/calvin/
PROD_DB = 192.168.1.16, 192.168.1.16

# sed -i 's/192.168.1.16/192.168.1.22/' database.txt
# cat database.txt
LOCAL_DATABASE = 192.168.1.22
LOCAL_DIR = /home/calvin/
PROD_DB = 192.168.1.22, 192.168.1.16

마지막 줄을 보면 두 번째 IP 주소는 그대로 남아 있는 것을 알 수 있습니다. 줄 안의 모든 항목을 교체하려면 반드시 g 옵션을 붙여야 합니다.

디렉터리 전체에서 찾아 바꾸기 – 진짜 마법

이제 진짜 마법 같은 부분입니다. 단일 파일이 아니라 현재 디렉터리의 모든 텍스트 파일에서 특정 문자열을 교체하고 싶다면 어떻게 해야 할까요? 예를 들어 여러 텍스트 파일에 등장하는 "wine"을 "champagne"으로 바꿔야 한다고 가정해 봅시다.

# find . -maxdepth 1 -name "*.txt" -type f -exec sed -i 's/wine/champagne/' {} \;

find 명령어 분석

  • find . : 현재 디렉터리(.)에서 검색을 시작합니다.
  • -maxdepth 1 : 하위 디렉터리로 더 들어가지 않고 현재 디렉터리만 검색합니다.
  • -name "*.txt" : 확장자가 .txt인 파일만 대상으로 삼습니다.
  • -type f : 디렉터리가 아닌 일반 파일만 선택합니다.
  • -exec ... {} \; : 검색된 각 파일에 대해 뒤따르는 명령(sed 치환)을 실행합니다. {} 자리에 검색된 파일 이름이 순서대로 대입됩니다.

이 명령 하나로 현재 디렉터리의 모든 .txt 파일에서 "wine"이 "champagne"으로 일괄 교체됩니다. 참고로 각 줄의 모든 항목까지 확실하게 바꾸려면 sed 치환문 끝에 g 옵션을 추가하면 됩니다. 또한 하위 폴더까지 모두 탐색하고 싶다면 -maxdepth 옵션을 제거하거나 값을 늘리면 됩니다.

마무리

sed와 find의 조합은 리눅스에서 반복적인 텍스트 편집 작업을 자동화하는 가장 기본적이면서도 강력한 방법입니다. 설정 파일 관리, 로그 정리, 코드 리팩토링 등 활용 범위가 무궁무진하니 꼭 익혀 두시기 바랍니다. 파일 안의 내용을 찾아 바꾸는 방법을 익혔다면, 다른 리눅스 활용 팁도 함께 확인해 보세요!