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

您需要使用 awkgetline将输出读入变量。您还需要正确设置区域设置,以便重新编码能够按预期工作。尝试这个:

$ 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 sel用来提取节点下的节点的副本/root/DESCRIPTION。这就是它的xmlstarlet sel -t -c '/root/DESCRIPTION/*' file.xml作用,它返回字符串<p>foo</p><p> </p><p> </p>

/root/DESCRIPTION然后通过命令将该字符串用作节点的新文本值xmlstarlet ed。新值来自命令替换。

请注意,该值会自动进行 XML 编码。

相关内容