sed를 사용하여 정규식 캡처 그룹 콘텐츠 교체

sed를 사용하여 정규식 캡처 그룹 콘텐츠 교체

다음과 같은 줄이 포함된 nginx.conf 파일을 프로그래밍 방식으로 편집하려고 합니다.

        access_log /var/log/nginx/access.log;

나는 그것이 다음과 같이 보이기를 원합니다 :

        access_log /dev/stdout;

나는 정규 표현식을 믿는다^\s*access_log([^;]*);캡처 그룹의 일부를 캡처 /var/log/nginx/access.log하지만 캡처 그룹을 sed로 올바르게 대체하는 방법을 잘 모르겠습니다.

나는 노력했다

echo "        access_log /var/log/nginx/access.log;" | sed 's/^\s*access_log([^;]*);/\1\\\/dev\\\/stdout/'

하지만 오류가 발생합니다.

sed: -e expression #1, char 45: invalid reference \1 on `s' command's RHS

시도하면 sed -r오류가 나타나지 않지만 출력은 예상한 것과 다릅니다.

 /var/log/nginx/access.log\/dev\/stdout

배포 시 기본 로그 파일 위치가 변경되는 경우 "access_log /var/log/nginx/access.log;"를 직접 검색하는 대신 그룹 캡처와 같은 작업에 대해 현명하게 노력하고 있습니다.

답변1

여기에는 몇 가지 오류가 있습니다.

먼저 sed기본 정규식을 사용하고 있으므로 캡처링 그룹을 생성 \(해야 합니다. \)-r스위치를 사용하면 확장 정규식을 사용할 수 있으므로 오류가 발생하지 않습니다. 바라보다정규식 문자를 정규식 문자로 해석하기 위해 sed에서 정규식 문자를 이스케이프 처리해야 하는 이유는 무엇입니까?.

둘째, 캡처 그룹을 잘못된 위치에 배치했습니다. 내가 올바르게 이해했다면 다음과 같이 할 수 있습니다.

sed -e 's!^\(\s*access_log\)[^;]*;!\1 /dev/stdout;!' your_file

!슬래시를 이스케이프 처리하지 않으려면 정규식 구분 기호로 를 사용하는 점에 유의하세요 /dev/stdout.

답변2

\No.정규식에서 이것이 무엇인지 알아야합니다 .역참조괄호 안의 패턴 (). 따라서 정규식은 다음과 같아야 합니다.'s@^(\s*access_log ).*$@\1/dev/stdout/;@'

나는 제공할 수 있다

sed '/access_log/s|/[^;]\+|/dev/stdout|'

/팁: 패턴 내에서 사용할 것인지 여부에 관계없이 원하는 s///모든 기호를 자유롭게 변경할 수 있습니다.s###

답변3

캡쳐하는 대신 그냥 찾아서 교체하면 어떨까요? 즉:

sed "/access_log/ s| /.*;| /dev/stdout;|"

" "와 일치하는 줄을 검색한 다음 access_log일치하는 줄에서 " " /whatever/path/is/there;를 " /dev/stdout;" 로 바꿉니다.

관련 정보