여러 줄 코드를 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에서 이 작업을 수행하고 싶습니다. "종결 이전에 아무 것도 없다고 가정할 수 있다면 "다음을 수행할 수 있습니다.

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

-0전체 파일을 후루룩 소리내어 메모리로 읽어 들입니다 . " -p에서 제공하는 스크립트를 적용한 후 "모든 줄(여기서 "줄"은 전체 파일이 됨)을 인쇄함)을 의미 합니다 -e. 스크립트 자체는 간단한 대체 연산자입니다. text0개 이상의 공백 문자 =와 0개 이상의 공백이 뒤따르는 문자열 ( text\s*=\s*)을 캡처하여 로 저장합니다 $1. 그런 다음 캡처된 패턴과 찾은 가장 짧은 인용 문자열을 패턴 ( $1) 및 으로 바꿉니다 "". 플래그 는 개행 문자와 일치 s합니다 ..

관련 정보