텍스트 파일로 작업할 때 하나 이상의 파일에서 텍스트 문자열을 찾아 교체해야 하는 경우가 많습니다.
sed는 스트림 편집기입니다. 파일 및 입력 스트림(예: 파이프라인)에 대해 기본 텍스트 조작을 수행할 수 있습니다. sed를 사용하면 단어와 행을 검색, 찾기 및 바꾸기, 삽입 및 삭제할 수 있습니다. 이 도구는 복잡한 패턴을 일치시킬 수 있는 기본 정규식과 확장된 정규식을 지원합니다.
문자열을 찾고 sed로 대체하는 방법에 대해 알아보겠습니다. 또한 재귀 검색 및 바꾸기를 수행하는 방법도 알려드립니다.
문자열을 찾아 sed로 변경
몇 가지 버전의 sed가 있으며 기능적으로 차이가 있습니다. macOS는 BSD 버전을 사용하는 반면, 대부분의 Linux 배포는 기본적으로 GNU sed가 미리 설치되어 있습니다. GNU 버전을 사용하겠습니다.
sed를 사용하여 텍스트를 검색하고 대체하는 일반적인 형식은 다음과 같습니다.
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
-i - 기본적으로 sed는 출력을 표준 출력에 씁니다. 이 옵션은 제자리에 있는 파일을 편집하도록 되어 있습니다. 확장자가 제공된 경우(ex -i.bak) 원래 파일의 백업이 생성됩니다.
s - substitute 명령으로, sed에서 가장 많이 사용되는 명령일 수 있습니다.
/ / / - 구분 기호 문자입니다. 임의의 문자일 수 있지만 일반적으로 슬래시(/) 문자가 사용됩니다.
SEARCH_REGEX - 검색할 일반 문자열 또는 정규식입니다.
REPLACEMENT - 교체 문자열입니다.
g - 전역 대체 플래그입니다. 기본적으로 sed는 파일을 한 줄씩 읽고 한 줄에서 첫 번째 항목만 변경합니다. 교체 플래그가 제공되면 모든 항목이 교체됩니다.
INPUTFILE - 명령을 실행할 파일의 이름입니다.
셸 메타 문자가 확장되지 않도록 인수 주위에 따옴표를 넣는 것이 좋습니다.
sed 명령을 사용하여 파일의 텍스트를 검색하고 가장 일반적으로 사용되는 옵션 및 플래그로 바꾸는 방법을 알아보겠습니다.
데모 목적으로 다음 파일을 사용할 것입니다.
# file.txt
123 Foo foo foo
foo /bin/bash Ubuntu foobar 456
g 플래그를 생략하면 각 행에 있는 검색 문자열의 첫 번째 인스턴스만 바뀝니다.
sed -i 's/foo/linux/' file.txt
# 123 Foo linux foo
# linux /bin/bash Ubuntu foobar 456
전역 대체 플래그를 사용하면 검색 패턴의 모든 항목이 바뀝니다.
sed -i 's/foo/linux/g' file.txt
# 123 Foo linux linux
# linux /bin/bash Ubuntu linuxbar 456
앞서 살펴본 바와 같이 foobar 문자열 내부의 하위 문자열 푸도 이전 예에서 대체되었습니다. 이것이 원하는 동작이 아닌 경우 검색 문자열의 양쪽 끝에 단어 경계식(\b)을 사용하십시오. 이렇게 하면 부분 단어가 일치하지 않습니다.
sed -i 's/\bfoo\b/linux/g' file.txt
# 123 Foo linux linux
# linux /bin/bash Ubuntu foobar 456
패턴 일치 대소문자를 구분하지 않도록 하려면 I 플래그를 사용합니다. 아래 예에서는 g 플래그와 I 플래그를 모두 사용합니다.
sed -i 's/foo/linux/gI' file.txt
# 123 linux linux linux
# linux /bin/bash Ubuntu linuxbar 456
구분 문자(/)가 포함된 문자열을 찾아서 바꾸려면 슬래시를 이스케이프하려면 백슬래시(\)를 사용해야 합니다. 예를 들어 /bin/bash를 /usr/bin/zsh로 바꾸려면 다음과 같이 하십시오.
sed -i 's/\/bin\/bash/\/usr\/bin\/zsh/g' file.txt
더 쉽고 읽기 쉬운 옵션은 다른 구분 문자를 사용하는 것입니다. 대부분의 사용자는 세로 막대(|) 또는 콜론(:)을 사용하지만 다른 문자는 사용할 수 있습니다.
sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt
# 123 Foo foo foo
# foo /usr/bin/zsh Ubuntu foobar 456
정규 표현식을 사용할 수도 있습니다. 예를 들어, 세 자리 숫자를 모두 검색하여 문자열 번호로 바꾸려면 다음과 같이 하십시오.
sed -i 's/\b[0-9]\{3\}\b/number/g' file.txt
# number Foo foo foo
# foo /bin/bash demo foobar number
sed의 또 다른 유용한 기능은 일치하는 패턴에 해당하는 앰퍼샌드 문자 &를 사용할 수 있다는 것입니다. 이 문자는 여러 번 사용할 수 있습니다.
예를 들어, 각 3자리 숫자에 중괄호 {}을(를) 추가하려면 다음을 입력하십시오.
sed -i 's/\b[0-9]\{3\}\b/{&}/g' file.txt
# {123} Foo foo foo
# foo /bin/bash demo foobar {456}
마지막으로, sed로 파일을 편집할 때는 항상 백업을 만드는 것이 좋습니다. 이렇게 하려면 백업 파일의 확장자를 -i 옵션에 제공하기만 하면 됩니다. 예를 들어 file.txt를 누르고 원본 파일을 file.txt.bak으로 저장하고 사용합니다.
sed -i.bak 's/foo/linux/g' file.txt
백업이 생성되었는지 확인하려면 ls 명령을 사용하여 파일을 나열하십시오.
ls
# file.txt file.txt.bak
반복적인 찾기 및 바꾸기
때로는 문자열을 포함하는 파일을 재귀적으로 검색하여 모든 파일에서 문자열을 바꿀 수 있습니다. 이 작업은 find 또는 grep와 같은 명령을 사용하여 디렉터리에서 파일을 반복적으로 찾고 sed에 파일 이름을 파이프링할 수 있습니다.
다음 명령은 현재 작업 디렉토리의 파일을 반복적으로 검색하여 파일 이름을 sed로 전달합니다.
find . -type f -exec sed -i 's/foo/bar/g' {} +
이름에 공백이 포함된 파일의 문제를 방지하려면 파일 이름을 인쇄한 다음 null 문자를 지정하고 xargs -0을 사용하여 출력을 sed로 파이핑하도록 알려주는 -print0 옵션을 사용하십시오.
find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'
디렉터리를 제외하려면 -not -path 옵션을 사용합니다. 예를 들어, 점(.)으로 시작하는 모든 파일을 제외하도록 로컬 git repo에서 문자열을 바꾸려면 다음을 사용합니다.
find . -type f -not -path '*/\.*' -print0 | xargs -0 sed -i 's/foo/bar/g'
특정 확장명의 파일에서만 텍스트를 검색하고 바꾸려면 다음을 사용합니다.
find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'
또 다른 옵션은 grep 명령을 사용하여 검색 패턴이 포함된 모든 파일을 재귀적으로 찾은 다음 파일 이름을 sed로 파이핑하는 것입니다.
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'
복잡해 보일 수 있지만, 처음에는 파일의 텍스트를 sed로 검색하고 바꾸는 것이 매우 간단합니다.
sed 명령, 옵션 및 플래그에 대한 자세한 내용은 GNU sed 설명서 및 Grymoiresed 튜토리얼을 참조하십시오.
'SW > 리눅스' 카테고리의 다른 글
Linux : 수신 포트 확인 방법, 예제, 명령어 (사용 중인 포트) (0) | 2021.11.29 |
---|---|
CentOS : Sudoers에 User를 추가 방법, 예제, 명령 (0) | 2021.11.28 |
Linux : Bash : Variable 증가, 감소 방법, 예제, 명령어 (카운터) (0) | 2021.11.26 |
Linux : Hostname 변경, 설정 방법, 예제, 명령어 (0) | 2021.11.25 |
Linux : IP Address 조회, 얻는 방법, 예제, 명령어 (0) | 2021.11.24 |