awk: 명령 구문 분석을 사용하여 행을 자체적으로 변경합니다. 여러 줄 문자

awk: 명령 구문 분석을 사용하여 행을 자체적으로 변경합니다. 여러 줄 문자

질문에 대답하려고합니다. 여기에는 명령 사용이 포함됩니다 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>&lt;p&gt;foo&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;</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 
    &lt;DESCRIPTION&gt;&lt;p&gt;foo&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;/DESCRIPTION&gt;

답변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>&lt;p&gt;foo&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;</DESCRIPTION>
  <URL>bar</URL>
  <IMGURL>foo</IMGURL>
  <IMGURL_ALTERNATIVE/>
</root>

여기서 일어나는 일은 xmlstarlet selnode 아래에 있는 노드의 복사본을 가져오는 데 사용된다는 것입니다 /root/DESCRIPTION. 그것이 xmlstarlet sel -t -c '/root/DESCRIPTION/*' file.xml하는 일입니다. string 을 반환합니다 <p>foo</p><p> </p><p> </p>.

/root/DESCRIPTION그런 다음 이 문자열은 명령을 통해 노드의 새 텍스트 값으로 사용됩니다 xmlstarlet ed. 새로운 값은 명령 대체에서 나옵니다.

이 값은 자동으로 XML로 인코딩됩니다.

관련 정보