질문에 대답하려고합니다. 여기에는 명령 사용이 포함됩니다 recode
. 명령은 특정 행을 구문 분석하고 나머지는 변경하지 않아야 합니다. 파일은 xml
파일입니다. 예:
<ITEM_ID>foo</ITEM_ID>
<PRODUCTNAME>bar</PRODUCTNAME>
<DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
<URL>bar</URL>
<IMGURL>foo</IMGURL>
<IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE>
원하는 출력은 다음과 같아야 합니다.
<ITEM_ID>foo</ITEM_ID>
<PRODUCTNAME>bar</PRODUCTNAME>
<DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
<URL>bar</URL>
<IMGURL>foo</IMGURL>
<IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE>
참고: 이 명령은 recode
예상대로 작동합니다. 레이블 변환을 피하는 것은 DESCRIPTION
나중에 해결할 수 있으며 문제의 일부가 아닙니다.
변경해야 할 줄은 로 시작하는 줄입니다 <DESCRIPTION>
.
저는 awk
스틸 사진을 잘 못 찍는데, 예상되는 명령은 다음과 같습니다.
awk '/<DESCRIPTION>/ { $0 = print $0 "| recode ..html" }1' foo.txt
물론 이것은 작동하지 않습니다.
이 목표를 어떻게 달성해야 합니까?
답변1
getline
출력을 변수로 읽으려면 awk를 사용해야 합니다 . 또한 녹음이 예상대로 작동하도록 로케일을 올바르게 설정해야 합니다. 이 시도:
$ LC_ALL=C gawk '/DESCRIPTION/{
"echo \""$0"\" | recode ..html" | getline ff; print ff
}' file
<DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
답변2
문서가 잘 구성되어 있고 일부 루트 노드가 있다고 가정합니다 root
.
$ cat file.xml
<root>
<ITEM_ID>foo</ITEM_ID>
<PRODUCTNAME>bar</PRODUCTNAME>
<DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
<URL>bar</URL>
<IMGURL>foo</IMGURL>
<IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE>
</root>
그 다음에,
$ xmlstarlet ed -u '/root/DESCRIPTION' -v "$( xmlstarlet sel -t -c '/root/DESCRIPTION/*' file.xml )" file.xml
<?xml version="1.0"?>
<root>
<ITEM_ID>foo</ITEM_ID>
<PRODUCTNAME>bar</PRODUCTNAME>
<DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
<URL>bar</URL>
<IMGURL>foo</IMGURL>
<IMGURL_ALTERNATIVE/>
</root>
여기서 일어나는 일은 xmlstarlet sel
node 아래에 있는 노드의 복사본을 가져오는 데 사용된다는 것입니다 /root/DESCRIPTION
. 그것이 xmlstarlet sel -t -c '/root/DESCRIPTION/*' file.xml
하는 일입니다. string 을 반환합니다 <p>foo</p><p> </p><p> </p>
.
/root/DESCRIPTION
그런 다음 이 문자열은 명령을 통해 노드의 새 텍스트 값으로 사용됩니다 xmlstarlet ed
. 새로운 값은 명령 대체에서 나옵니다.
이 값은 자동으로 XML로 인코딩됩니다.