다음 내용이 포함된 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>
ipaddr
및 subnet
노드가 동일한 상위 노드의 하위인 경우 아래와 같이 명령이 훨씬 간단하고 오류 발생 가능성이 적습니다.
<?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>