나는 sed
/ 및 일반적인 정규식의 세계에 대해 매우 익숙하지 않으며 사용법을 조사해 왔지만 필요한 사항에 어려움을 겪고 있습니다.awk
htm
레이블 역할을 하는 두 주석 사이에 사용자가 입력한 텍스트(셸 스크립트를 통해)로 업데이트해야 하는 한 줄 알림이 있는 페이지가 있습니다 . 예를 들면 다음과 같습니다.
<!--BeginNoticeMSG-->NOTICE: This is a notice<!--EndNoticeMSG-->
그런 다음 사용자가 입력한 텍스트(변수에 저장되어 있음 $NEWNOTICE
)는 태그 사이의 내용을 바꿔야 하므로 다음과 같이 작동합니다.
<!--BeginNoticeMSG-->$NEWNOTICE<!--EndNoticeMSG-->
파일 에 삽입됩니다 htm
(예:).
<!--BeginNoticeMSG-->This is a test notice<!--EndNoticeMSG-->
태그 사이의 텍스트를 올바르게 식별하고 바꾸는 방법은 무엇입니까?
답변1
이것은 지정된 대로만 귀하의 요구를 충족시키는 (상당히) 기본 레시피입니다.
#!/bin/bash
REPLACEWITH="Your replacement text here"
STARTTAG="BeginNoticeMSG"
ENDTAG="EndNoticeMSG"
sed -E "s/(<\!\-\-$STARTTAG\-\->)(.*)(<\!\-\-$ENDTAG\-\->)/\1$REPLACEWITH\3/" -i target_file.html
입력이 다르면 여러 가지 방식으로 분리됩니다. 특히 입력 "레이블"이 여러 줄로 분리되는 경우 더욱 그렇습니다.
정규식을 사용하여 HTML 및 XML을 처리하는 것은 일반적으로 권장되지 않습니다(이것은 단지 주석일 뿐이라는 것을 알고 있습니다). 그러나... 이 기사에서 제안하는 것처럼 입력이 신뢰할 수 있는 경우 이 간단한 접근 방식이 작동할 수 있습니다.
이 경우 대체 항목을 입력하는 데 필요한 텍스트의 양을 줄이기 위해 레이블의 일부를 \1
및 \3
(정규식의 괄호 안 항목과 관련)로 역참조했습니다.
또는 -E
옵션도 없고 역참조도 없습니다.
#!/bin/bash
REPLACEWITH="Text to replace with here"
STARTTAG="BeginNoticeMSG"
ENDTAG="EndNoticeMSG"
sed -e "s/<\!\-\-$STARTTAG\-\->.*<\!\-\-$ENDTAG\-\->/<\!\-\-$STARTTAG\-\->$REPLACEWITH<\!\-\-$ENDTAG\-\->/" -i target_file.html
답변2
같은 줄에 여러 개의 공지가 없다고 가정합니다(보다 정확하게는 <!--BeginNoticeMSG-->
같은 줄에 여러 개의 공지가 있을 수 없음).<!--EndNoticeMSG-->
sed -e "s&\(<!--BeginNoticeMSG-->\).*\(<!--EndNoticeMSG-->\)&\1$NEWNOTICE\2&"
여는 주석과 닫는 주석이 다를 수 있는 경우 해당 주석에 대한 정규식을 작성할 수 있습니다.
이는 , 또는 개행 문자를 $NEWNOTICE
포함하지 않는 것이 확실한 경우에만 작동합니다. 그렇지 않으면 이러한 문자는 sed 구문으로 해석됩니다.\
&
구두점 견고성을 높이려면 대신 awk를 사용하세요.
export NEWNOTICE
awk '{sub(/<!--BeginNoticeMSG-->.*<!--EndNoticeMSG-->/, "<!--BeginNoticeMSG-->" env[NEWNOTICE] "<!--EndNoticeMSG-->"); print}'