개행 문자와 탭으로 sed/awk 문자열 대체

개행 문자와 탭으로 sed/awk 문자열 대체

다음 내용이 포함된 XML 파일이 있습니다.

<ipaddr>192.168.1.1</ipaddr>
    <subnet>24</subnet>

목표는 하나의 명령으로 <ipaddr>192.168.1.1</ipaddr>to <ipaddr>192.168.1.125</ipaddr>와 to를 수정하는 것입니다 <subnet>24</subnet>. <subnet>25</subnet>파일 내의 다른 서브넷 태그를 변경하고 싶지 않습니다.

내가 겪고 있는 문제는 그 뒤에 개행 문자가 있고 </ipaddr>그 앞에 두 개의 탭 문자가 있다는 것입니다 <subnet>.

나는 이것을 시도했지만 awk '{gsub (/<ipaddr>192.168.1.1<\/ipaddr>\n<subnet>24<\/subnet>/, "<ipaddr>192.168.1.125<\/ipaddr>\n\t\t<subnet>25<\/subnet>")}' config.xml 작동하지 않습니다.

누군가 나에게 올바른 방향을 알려줄 수 있습니까?

답변1

한 줄에서는 IP를 변경하고 다음 줄에서는 서브넷을 변경한다고 가정해 보겠습니다.

 sed -E '/(192.168.1.)1/{s//\1125/; n; s/>24</>25</}' infile

IP는 변경되지만 서브넷은 변경되지 않는 경우 오류가 보고되지 않습니다. 귀하의 설명에 따르면 이것이 귀하가 원하는 것 같습니다.

답변2

이는 다소 불완전한 사양입니다. 우리는 무엇을 찾고 있나요? 일반적인 패턴이 있나요? 정확한 IP 주소와 서브넷은 무엇입니까? 그렇다면 시도해 보세요.

$ sed -r '/(192.168.1.)1/{s//\1125/; N; s/24/25/}' file
<ipaddr>192.168.1.125</ipaddr>
          <subnet>25</subnet>

답변3

데이터가 다음과 같이 올바른 형식의 XML 문서라고 가정합니다.

<?xml version="1.0"?>
<root>
  <ipaddr>192.168.1.2</ipaddr>
  <subnet>24</subnet>
  <ipaddr>192.168.1.1</ipaddr>
  <subnet>24</subnet>
</root>

다음 XMLStarlet 명령은 ipaddr현재 값이 192.168.1.1이고 첫 번째 subnet형제가 24인 노드를 찾아 ipaddr노드 값을 로 변경합니다 192.168.1.125. 그런 다음 유사한 작업을 수행하여 subnet노드 값을 25로 변경하고 노드의 새 값을 사용하여 ipaddr위치를 지정합니다.

xmlstarlet ed \
    -u '//ipaddr[. = "192.168.1.1" and following-sibling::subnet[1] = "24"]' -v '192.168.1.125' \
    -u '//subnet[. = "24" and preceding-sibling::ipaddr[1] = "192.168.1.125"]' -v 25 file.xml

결과는 다음과 같습니다

<?xml version="1.0"?>
<root>
  <ipaddr>192.168.1.2</ipaddr>
  <subnet>24</subnet>
  <ipaddr>192.168.1.125</ipaddr>
  <subnet>25</subnet>
</root>

ipaddrsubnet노드가 동일한 상위 노드의 하위인 경우 아래와 같이 명령이 훨씬 간단하고 오류 발생 가능성이 적습니다.

<?xml version="1.0"?>
<root>
  <host name="hostA">
    <ipaddr>192.168.1.2</ipaddr>
    <subnet>24</subnet>
  </host>
  <host name="hostB">
    <ipaddr>192.168.1.1</ipaddr>
    <subnet>24</subnet>
  </host>
</root>

host그런 다음 다음과 같이 간단히 노드 이름을 선택할 수 있습니다 .

xmlstarlet ed \
    -u '//host[@name="hostB"]/ipaddr' -v '192.168.1.125' \
    -u '//host[@name="hostB"]/subnet' -v '25' file.xml

생산

<?xml version="1.0"?>
<root>
  <host name="hostA">
    <ipaddr>192.168.1.2</ipaddr>
    <subnet>24</subnet>
  </host>
  <host name="hostB">
    <ipaddr>192.168.1.125</ipaddr>
    <subnet>25</subnet>
  </host>
</root>

관련 정보