여러 줄 코드를 sed로 바꾸는 방법?

특수 문자가있는 큰 파일이 있습니다. 로 바꾸고 싶은 멀티 라인 코드가 sed있습니다.

이:

  text = "\
    ------                                                           ------\n\n\
    This message was automatically generated by email software\n\
    The delivery of your message has not been affected.\n\n\
    ------                                                           ------\n\n"

이것으로 전환해야합니다 :

text = ""

다음 코드를 시도했지만 운이 없습니다.

sed -i '/  text = "*/ {N; s/  text = .*affected.\./  text = ""/g}' /etc/exim.conf

아무것도 대체하지 않으며 오류 메시지를 표시하지 않습니다

나는 그것을 가지고 놀고 있지만 시도하는 모든 것이 작동하지 않습니다.



답변

구조에 펄 :

perl -i~ -0777 -pe 's/text = "[^"]+"/text = ""/g' input-file
  • -i~ 파일을 “제자리에서”편집하고 백업 사본을 남깁니다.
  • -0777 한 줄씩이 아닌 전체 파일을 한 번에 읽습니다.

대체 s///는 sed에서와 유사하게 작동합니다 (즉 text = ", 큰 따옴표와 여러 번 큰 따옴표까지 일치 합니다).이 경우 전체 파일에서 작동합니다.


답변

패턴 공간을 확인하고 N일치하지 않는 경우 계속 연장선을 당겨야합니다.

sed '/text = "/{              # if line matches text = "
:b                            # label b
$!N                           # pull in the next line (if not the last one)
/"$/!bb                       # if pattern space doesn't end with " go to label b
s/".*"/""/                    # else remove everything between the quotes
}' infile

으로 gnu sed당신이로 쓸 수 있습니다

sed '/text = "/{:b;$!N;/"$/!bb;s/".*"/""/}' infile

그래도 효율적이지 않습니다. 범위를 선택 /text = "/,/"/하고 첫 번째 줄을 수정하고 나머지를 삭제하십시오.

sed '/text = "/,/"/{            # in this range
/text = "/!d                    # delete all lines not matching text = "
s/\\/"/                         # replace the backslash with quotes (this is only
}' infile                       # executed if the previous d wasn't executed)

다시 한번, gnu sed하나의 라이너로 작성할 수 있습니다.

sed '/text = "/,/"/{/text = "/!d;s/\\/"/}' infile

답변

개인적으로 나는 이것을 Perl에서 할 것이다. "폐회 전이 없다고 가정 "할 수 있다면 다음을 수행 할 수 있습니다.

perl -0pe 's/(text\s*=\s*)".*?"/$1""/s' file

-0메모리에 읽기, 전체 파일을 slurps. -p수단 “에 의해 주어진 스크립트를 적용한 후”(될 것입니다 전체 파일 라인 여기하는) 모든 라인을 인쇄 ” -e“. 스크립트 자체는 간단한 대체 연산자입니다. 문자열 text뒤에 0 개 이상의 공백 문자 =와 0 개 이상의 공백 문자를 다시 캡처하고 ( text\s*=\s*) 다른 이름으로 저장합니다 $1. 그런 다음 캡처 된 패턴과 가장 짧은 인용 문자열을 패턴 ( $1) 및으로 바꿉니다 "". s플래그하게 .일치 뉴 라인.