이 세 줄을 찾으려고합니다.
<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->
그것들을 다음으로 대체하십시오 :
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
내가 시도 할 때
sudo sed -i 's:<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml
그것을 찾지 못하고 \ n도 넣으려고했지만 여전히 작동하지 않습니다.
sudo sed -i 's:<!--\n <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />\n -->:<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />:' /myfile.xml
이것들은 오류를 던지지 않으며 단지 주석 처리를 제거하지 않습니다. 어떤 조언이라도 감사 할 것입니다!
답변
sed는 각 줄을 차례로 읽으므로 올바른 방향으로 움직이지 않으면 여러 줄 패턴과 일치하지 않습니다. 이 N
명령은 입력에서 한 줄을 읽고이를 패턴 공간에 추가합니다.
sed -i -e '/^<!--$/ {
N; /\n<Connector port="8009" protocol="AJP\/1\.3" redirectPort="8443" \/>$/ {
N; /\n-->$/ {
s/^<!--\n//; s/\n-->$//
}
}
}' /myfile.xml
아마도, 이외의 명령이 필요한 경우 s
sed에서 awk 또는 perl로 전환해야합니다. 보다 일반적인 방식으로 여러 줄 주석에 대처하는 약간 더 유연한 Perl 스 니펫이 있습니다.
perl -i -pe '
if (/<!--/) { $_ .= <> while !/-->/;
s[<!--\n(<Connector port="8009" protocol="AJP/1\.3" redirectPort="8443" />)\n-->][$1];
}' /myfile.xml
답변
Sed는 라인 단위로 작동합니다. 여러 줄에서 작동하도록 만들 수는 있지만 그런 식으로 설계되지는 않았습니다. 내 의견으로는 그렇게 사용하려고 할 때 확실히 보여줍니다. 그러나 그렇게하기로 결정했다면 아마도 레지스터를 사용해야 할 것입니다. /programming/1251999/sed-how-can-i-replace-a-newline-n 에 대한 솔루션 중 일부를 확인 하여 수행 방법을 확인하십시오.
나는 이런 종류의 작업을 위해 sed 대신 perl을 사용하는 것을 선호합니다 (멀티 라인 지향, 나는 의미합니다). 검색 및 교체 ( BEGIN...
) 전에 추가 해야하는 상용구 는 분명하지 않지만 정규 표현식이 더 깨끗해 보입니다.
perl -i.bak -pe 'BEGIN{undef $/;} s/<!--string-->/string/smg' file.xml
또는 그룹화를 사용하여 표현식을 줄이고 정규 표현식을 사용할 수 있습니다.
perl -i.bak -pe 'BEGIN{undef $/;} s/<!--(string_or_regex)-->/\1/smg' file.xml
주석 표시와 주석 처리를 해제 할 코드 사이에 줄 바꿈이 있거나없는 경우 모두에서 작동해야합니다.
적응 :
답변
SED의 여러 줄 명령에 대한 설명은 다음과 같습니다. http://docstore.mik.ua/orelly/unix/sedawk/ch06_01.htm
엉덩이가 아파요. Eduardo의 조언을 따르고 perl -i -p -e
대신 사용할 수 있습니다 .
답변
/<\!--/
: 일치하는 문자열:X
: 분기 명령 “b”의 레이블입니다./-->/
: 일치하는 문자열s@...@...@p
: “<!-“, “->”를 제거하고 인쇄 결과d
: 패턴 공간을 삭제하고 새주기를 시작합니다N
: /-> /와 일치하지 않으면 줄을 추가하십시오.bX
: 분기에서 : X 레이블로p
: / <!-/와 일치하지 않는 문자열을 인쇄하십시오.
sed -rn '
/<!--/ {
:X
/-->/ {
s@<!--\s*(<.+/>)\s*-->@\1@p
d
}
N
bX
};p'
그리고이 두 번째 방법은 일반적인 작은 크기의 텍스트 파일 (쉘 스크립트 파일 필요)을 간단한 복사 및 붙여 넣기로 대체합니다.
#!/bin/bash
# copy & paste content that you want to substitute
AA=$( cat <<\EOF | sed -z -e 's#\([][^$*\.#]\)#\\\1#g' -e 's#\n#\\n#g'
<!--
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
-->
EOF
)
BB=$( cat <<\EOF | sed -z -e 's#\([&\#]\)#\\\1#g' -e 's#\n#\\n#g'
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
EOF
)
sed -z -i 's#'"${AA}"'#'"${BB}"'#g' *.xml # apply to all *.xml files