특수 문자가있는 큰 파일이 있습니다. 로 바꾸고 싶은 멀티 라인 코드가 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
플래그하게 .
일치 뉴 라인.