여러 줄의 코드를 sed로 바꾸는 방법은 무엇입니까?

여러 줄의 코드를 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

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

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

답변1

Perl이 구조에 옵니다:

perl -i~ -0777 -pe 's/text = "[^"]+"/text = ""/g' input-file
  • -i~파일은 "제자리"에서 편집되며 백업 사본은 남겨집니다.
  • -0777한 줄씩 읽는 대신 전체 파일을 한 번에 읽어보세요.

교체는 s///sed와 유사하게 작동합니다(즉, text = "큰따옴표를 제외한 모든 항목, 최대 큰따옴표까지 여러 번 일치). 그러나 이 경우 전체 파일에 적용됩니다.

답변2

패턴 공간을 확인해야 하며 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

답변3

개인적으로 저는 Perl을 사용하여 이 작업을 수행하겠습니다. "end 전에 아무 것도 없다고 가정할 수 있다면 "다음과 같이 할 수 있습니다.

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

-0전체 파일을 먹고 메모리로 읽습니다. 주어진 스크립트를 "적용한 후" 각 라인을 인쇄한다는 의미입니다 -p(여기서 "라인"은 전체 파일이 됩니다) -e. 스크립트 자체는 간단한 대체 연산자입니다. text0개 이상의 공백 문자가 뒤따르는 문자열을 캡처한 다음 =0개 이상의 공백 문자( text\s*=\s*)를 캡처하여 로 저장합니다 $1. 그런 다음 $1캡처된 패턴을 패턴( ) 및 가장 짧은 인용 문자열로 바꿉니다 "". 이 s플래그를 사용하면 .개행 문자가 일치됩니다.

관련 정보