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


16

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 '/access_log/s|/[^;]\+|/dev/stdout|'
Costas

@ 코스타 당신이 그 대답을 할 수 있다면 나는 또한 당신을 찬성합니다!
Abe Voelker

답변:


16

몇 가지 실수가 있습니다.

첫째, 이후 sed사용하는 기본 정규식이 필요 \(하고 \)캡처 그룹을 만들 수 있습니다. 이 -r스위치는 확장 정규식을 활성화하므로 오류가 발생하지 않습니다. 정규식 문자로 해석하려면 sed에서 정규식 문자를 이스케이프해야하는 이유를 참조하십시오 . .

둘째, 캡처 그룹을 잘못된 위치에두고 있습니다. 내가 당신을 올바르게 이해한다면, 당신은 이것을 할 수 있습니다 :

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

!에서 슬래시를 피하기 위해 정규식 구분 기호로 사용하십시오 /dev/stdout.


고마워요, 훌륭하게 작동합니다! 아직 승인 된 것으로 표시 할 수 없지만 9 분 후에 다시 표시됩니다.
Abe Voelker

1
@AbeVoelker 천만에요. 도와 드리겠습니다.
Joseph R.

5

정규 표현식 에서 괄호 안의 패턴에 \No.대한 역 참조 임을 알아야합니다 (). 따라서 정규 표현식은's@^(\s*access_log ).*$@\1/dev/stdout/;@'

나는 제안 할 수있다

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

힌트 : /patern 내부에서 사용하려는 경우 예를 들어 s///원하는 모든 심볼에 대해 자유롭게 변경할 수 있습니다.s###


감사합니다. 두 가지 답변을받을 수 있으면 좋겠습니다. 더 이상 솔루션을 본 후 도움을 요청하기 전에 매뉴얼 페이지를 완전히 읽지 않은 것을 후회하지 않습니다.
Abe Voelker

3

그것을 포착하는 대신 그것을 찾아서 대체하는 것이 어떻습니까? 즉 :

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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.