使用 Linux 工具从 XML 文档中删除元素属性

Removing element attributes from XML document using Linux tools

我确实有一个包含类似于以下行的文件:

<Item Name="INV_LIST" Justification="End" LowestAllowedValue="" DistanceBetweenRecords="0" Width="45" MaximumLength="12" SynchronizedItemName="INVOICE_AMT" PromptDisplayStyle="First Record"/>
<Item Name="INVOICE_AMT_LIST" Justification="End" LowestAllowedValue="" DistanceBetweenRecords="0" Width="48" MaximumLength="22" SynchronizedItemName=""  PromptDisplayStyle="First Record"/>
<Item Name="INV_LIST2" Justification="End" LowestAllowedValue="" DistanceBetweenRecords="0" Width="233" MaximumLength="12" SynchronizedItemName="INVOICE_AMT2" PromptDisplayStyle="First Record"/>

我想 运行 一个像 sed 或 awk 这样的 Linux 命令来删除属性 MaximumLength 及其值(无论引号之间包含什么)只要有一行包含具有值的 SynchronizedItemName。如果该行包含 SynchronizedItemName="",该行将保持不变。

我想以以下结尾:

<Item Name="INV_LIST" Justification="End" LowestAllowedValue="" DistanceBetweenRecords="0" Width="45" SynchronizedItemName="INVOICE_AMT" PromptDisplayStyle="First Record"/>
<Item Name="INVOICE_AMT_LIST" Justification="End" LowestAllowedValue="" DistanceBetweenRecords="0" Width="48" MaximumLength="22" SynchronizedItemName=""  PromptDisplayStyle="First Record"/>
<Item Name="INV_LIST2" Justification="End" LowestAllowedValue="" DistanceBetweenRecords="0" Width="233" SynchronizedItemName="INVOICE_AMT2" PromptDisplayStyle="First Record"/>

您可以尝试使用这个 awk 脚本:

{
where = match([=10=], "SynchronizedItemName=\"\"")
if (where != 0) print
else{
  gsub(/MaximumLength=\"[0-9]*\"/, ""); print
  }
}

根据您的输入,我得到的输出为:

<Item Name="INV_LIST" Justification="End" LowestAllowedValue="" DistanceBetweenRecords="0" Width="45"  SynchronizedItemName="INVOICE_AMT" PromptDisplayStyle="First Record"/>
<Item Name="INVOICE_AMT_LIST" Justification="End" LowestAllowedValue="" DistanceBetweenRecords="0" Width="48" MaximumLength="22" SynchronizedItemName=""  PromptDisplayStyle="First Record"/>
<Item Name="INV_LIST2" Justification="End" LowestAllowedValue="" DistanceBetweenRecords="0" Width="233"  SynchronizedItemName="INVOICE_AMT2" PromptDisplayStyle="First Record"/>

如果您有可用的 xmlstarlet,您可以使用 ed 命令...

注意:“-L”全局选项修改文件 in-place。如果您不想修改原始输入文件,请将其删除。

xmlstarlet ed -L -d '//Item[normalize-space(@SynchronizedItemName)]/@MaximumLength' input.xml

使用上面的 Pankaj 代码,把它放在正确的轨道上。 他的代码适用于我示例中的一小部分行和我添加的其他一些行,但在较大的文件中,它用 MaximumLength 替换了所有元素。

但是,我的解决方案是基于他的想法,所以再次感谢 Pankaj。

这是我最终得到的结果:

cat tempo | awk '{ ret = match([=10=], "SynchronizedItemName=\"[0-9A-Za-z_]+\"")
              if (ret > 0) {
                gsub(/MaximumLength=\"[0-9]*\"/, ""); print [=10=]
              }
              else {
                print [=10=]
              }
            }' > tmpo_file && mv tmpo_file tempo

最后一点(重定向),只是将文件打印到一个临时文件,然后替换原来的文件。