![XML 속성 값을 정리하는 방법](https://linux55.com/image/13488/XML%20%EC%86%8D%EC%84%B1%20%EA%B0%92%EC%9D%84%20%EC%A0%95%EB%A6%AC%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95.png)
다음과 같은 XML이 있습니다.
<string name="foo-bar">"bar-bar -bar"</string>
<string name="asdf_qwe-rty" translatable="false">"Lorem ipsum"</string>
이제 속성 에는 문자가 name
포함될 수 없으므로 .-
_
<string name="foo_bar">"bar-bar -bar"</string>
<string name="asdf_qwe_rty" translatable="false">"Lorem ipsum"</string>
을 사용하여 어떻게 할 수 있습니까 sed
?
답변1
XML 문서의 형식이 올바르다고 가정하면 다음을 사용하여 모든 노드 속성에서 xmlstarlet
모든 문자 발생을 바꿀 수 있습니다.-
name
string
_
$ xmlstarlet ed -u '//string/@name' -x 'translate(.,"-","_")' file.xml
<?xml version="1.0"?>
<root>
<string name="foo_bar">"bar-bar -bar"</string>
<string name="asdf_qwe_rty" translatable="false">"Lorem ipsum"</string>
<string name="_test1_">name="-test1-"</string>
<!-- <string name="-test2-">name="-test2-"</string> -->
</root>
root
( 문서 형식을 잘 만들기 위해 여기에 래퍼 노드를 추가했고 , 노드 값이나 주석 내용에 영향을 주지 않는다는 것을 보여주기 위해 몇 가지 추가 사례를 추가했습니다).
이 xmlstarlet
표현식은 XPath 표현식을 사용하여 모든 관련 속성을 찾고 각 속성 값 에 //string/@node
간단한 변환을 적용합니다 . 출력은 표준 출력에 기록됩니다.-
_
답변2
sed 기반 솔루션(또는 적절한 XML 구문 분석을 수행하지 않는 다른 솔루션)은 특정 비율의 극단적인 경우에 실패합니다. 예를 들어 @Pitel의 솔루션은 다음과 같습니다.
(a) 여는 태그가 아닌 주석이나 텍스트에 있더라도 이름 속성처럼 보이는 항목을 바꿉니다.
firstname
(b) 또는 이름이 지정된 속성의 내용도 변경합니다.lastname
(c) 등호 주위에 공백이 있으면 속성을 찾을 수 없습니다.
따라서 일회성 임시 사용에는 충분할 수 있지만 프로덕션 워크플로우에 포함시키지 마십시오. 프로덕션 품질의 자료가 필요한 경우 XSLT 변환을 사용하십시오. 어렵지 않습니다:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="@name">
<xsl:attribute name="name" select="translate(., '-', '_')"/>
</xsl:template>
</xsl:transform>
답변3
sed -r ':a; s/(name="[^-"]*)-/\1_/; ta'