Vim 또는 Sed의 복잡한 검색 및 바꾸기

Vim 또는 Sed의 복잡한 검색 및 바꾸기

나는 다음을 가지고 있습니다(형식을 보존하기 위해 내 등록에서 제거되었습니다. 아마도 그것이 내가 여기에 있는 이유일 것입니다).

<li><span>Concrete Patching (</span><span
        style="overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 16.00px; height: 16.00px;"><img
          alt=""
          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4XmP4//8dAwAI2gLt+1m1FgAAAABJRU5ErkJggg=="
          style="width: 16.00px; height: 16.00px; margin-left: -0.00px; margin-top: -0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);"
          title=""></span>)</li>
    <li><span>Paving (</span><span
        style="overflow: hidden; display: inline-block; margin: 0.00px 0.00px; border: 0.00px solid #000000; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px); width: 16.00px; height: 16.00px;"><img
          alt=""
          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4XmP4//8tAwAI2ALsJ7n0vAAAAABJRU5ErkJggg=="
          style="width: 16.00px; height: 16.00px; margin-left: -0.00px; margin-top: -0.00px; transform: rotate(0.00rad) translateZ(0px); -webkit-transform: rotate(0.00rad) translateZ(0px);"
          title=""></span>)</li> 

나는 그것이 다음이 되기를 원합니다: <li> Concrete Patching (flag) </li>, 그게 다입니다.

편집하다: 각 태그 내부의 문자열은 <li><span> (...어떤 문자열이든 될 수 있다는 점을 언급해야 합니다. <span>각각의 첫 번째 문자를 제거 <li>하고 까지 모두 유지한 (다음 최대 까지 모두 )로 바꾸고 싶습니다 flag. 명확히 하지 못해 죄송합니다.


이 패턴은 디렉터리의 모든 파일에 나타나므로 일괄 작업을 사용하는 sed것이 이상적이지만 이에 대해서는 확신이 없습니다. Vim단일 버퍼를 사용하여 :%s/<C-r>"끌어온 레지스터를 명령에 넣어서 이스케이프하고 싶은 항목(예: <\/span>newlines )을 이스케이프 처리 하려고 시도했지만 \r제대로 수행하지 못하고 있습니다.

위와 같이 복잡한 풀 블록에서 쉽게 플러그인을 수행할 수 있는 플러그인이 있다면 :%s사용하겠지만, 그 중 어느 것도 내가 필요한 방식으로 올바르게 수행하는 데 필요한 정규식 패턴을 존중하지 않는 것 같습니다.

저는 직장에서 거의 동일한 텍스트를 많이 교체하고 수동으로 편집하는 데 몇 시간이 걸리는 반면, 정규식 패턴을 사용하면 몇 분이 걸릴 수 있다는 것을 알고 있습니다. 어떤 제안이라도 자유롭게 보내주세요.

답변1

다음 -z옵션을 권장합니다 sed.

$ sed -z 's;<li><span>\([^(]*\)(</span><span[^<]*<img[^>]*></span>);<li> \1(flag) ;g' file
<li> Concrete Patching (flag) </li>
    <li> Paving (flag) </li> 

이는 "특정 패치"가 임의의 문자열일 수 있다는 점을 고려합니다.

-z, --null-data
                 separate lines by NUL characters

답변2

이렇게 하면 됩니다:

sed '/Concrete Patching/ s/<span>/ /; s/(<\/span><span/(flag) <\/li>/' your_file

작동 방식은 다음과 같습니다.

  • 가 포함된 줄에 대해 Concrete Patching다음 2가지 바꾸기를 수행합니다. 1) 첫 번째를 <span>공백으로 바꾸고, 2) 첫 번째를 다음 (<\/span><span/으로 바꿉니다.(flag) <\li>

원하는 대로 작동하는지 확인했으면 제자리 -i에 교체를 추가하세요.

sed -i '/Concrete Patching/ s/<span>/ /; s/(<\/span><span/(flag) <\/li>/' your_file

관련 정보