我有一个XML表,其行结构如下:
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>foobar</C3>
<C4>foobar</C4>
<C5>foobar</C5>
<C6>foobar</C6>
<C7>foobar</C7>
<C8>foobar</C8>
<C9>foobar</C9>
<C10>foobar</C10>
<C11>foobar</C11>
<C12>foobar</C12>
</row>
我想做的是在第12列之后添加第13列,该列需要有一个递增的数字作为其值,以用作主键(从1开始,每行增加1,例如X ++等等) 。值得注意的是,大约有2000万行。
我一直在尝试使用CygWin(Mintty)进行此操作,但是我对此完全没有经验,也没有任何Unix的经验,这只是我所建议的第一件事,它实际上能够加载这些怪异的XML。文件。
对于初学者,我尝试使用 Sed 通过以下命令插入第13列:
-i -e 's/\/C12>/\/C12><C13><\/C13>/g' t1s.txt
我的想法是,我将用自己的C13支架和第13列代替。相反,它只是将C12替换为C13,好像没有正确地转义斜线一样。
可能有一个命令“插入”而不是“替换”,这使我正在尝试做的事情看起来完全疯狂,但我不知道该命令将是什么,并且没有太多运气。如果Sed无法实现此功能,我最想使用的是AWK,但我不知道该怎么做,但我也不知道该怎么做,而且似乎也很难。
我希望实现的是按如下方式更改文档(很长,但显然不包括所有内容就没有意义。这个问题仅涉及如何在每行中添加第13列,即其他12个只是上下文):
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>foobar</C3>
<C4>foobar</C4>
<C5>foobar</C5>
<C6>foobar</C6>
<C7>foobar</C7>
<C8>foobar</C8>
<C9>foobar</C9>
<C10>foobar</C10>
<C11>foobar</C11>
<C12>foobar</C12>
<C13>1</C13>
</row>
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>foobar</C3>
<C4>foobar</C4>
<C5>foobar</C5>
<C6>foobar</C6>
<C7>foobar</C7>
<C8>foobar</C8>
<C9>foobar</C9>
<C10>foobar</C10>
<C11>foobar</C11>
<C12>foobar</C12>
<C13>2</C13>
</row>
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>foobar</C3>
<C4>foobar</C4>
<C5>foobar</C5>
<C6>foobar</C6>
<C7>foobar</C7>
<C8>foobar</C8>
<C9>foobar</C9>
<C10>foobar</C10>
<C11>foobar</C11>
<C12>foobar</C12>
<C13>3</C13>
</row>
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>foobar</C3>
<C4>foobar</C4>
<C5>foobar</C5>
<C6>foobar</C6>
<C7>foobar</C7>
<C8>foobar</C8>
<C9>foobar</C9>
<C10>foobar</C10>
<C11>foobar</C11>
<C12>foobar</C12>
<C13>4</C13>
</row>
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>foobar</C3>
<C4>foobar</C4>
<C5>foobar</C5>
<C6>foobar</C6>
<C7>foobar</C7>
<C8>foobar</C8>
<C9>foobar</C9>
<C10>foobar</C10>
<C11>foobar</C11>
<C12>foobar</C12>
<C13>5</C13>
</row>
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>foobar</C3>
<C4>foobar</C4>
<C5>foobar</C5>
<C6>foobar</C6>
<C7>foobar</C7>
<C8>foobar</C8>
<C9>foobar</C9>
<C10>foobar</C10>
<C11>foobar</C11>
<C12>foobar</C12>
<C13>6</C13>
</row>
这种情况持续了几百万行...
请注意,唯一的变化是增加了第13列,并且其值每行增加一次。这就是这个问题的全部,其他12列只是周围的结构。
答案 0 :(得分:2)
使用xmlstarlet
和XSLT转换:
提供此XSLT文件
$ cat f.xslt
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- Identity transform -->
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:for-each select="/doc/row">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<C13><xsl:value-of select="position()"/></C13>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
并假设<row>...</row>
包含在标签<doc>...</doc>
中,您可以使用以下命令将C13
节点及其计数添加到其中:
xmlstarlet tr f.xslt file
tr
的意思是“转置”,并使用XSLT文件修改给定的file
。
XSLT主要包含2个块。
一种称为“身份”的方式,将输入保持原样。第二个块查找每个<doc><row>
并复制其内容,并向<C13>
节点添加计数。
答案 1 :(得分:1)
要编辑XML文件,最好使用XML解析器。
以下是使用C13
(在Cygwin中可用)将包含文本foobar
的节点xmlstarlet
插入XML文件的命令:
xmlstarlet ed --subnode "/row" -t elem -n C13 -v foobar ts1.txt
ed
:编辑/更新XML文档--subnode "/row"
:在row
节点内添加一个节点-t elem
:类型为元素-n C13
:名称为C13
v foobar
:值是foobar
答案 2 :(得分:0)
如果您的输入确实是那么常规和简单,那么您所需要的就是:
awk '{print} sub(/<C12>.*/,""){print $0"<C13>"++cnt"</C13>"}' file
,但没有具体的依据来检验其猜测。这就是我认为的操作,您正在尝试使用每个块有2个foobar而不是12个foobar的MCVE:
$ cat file
<row>
<C1>foobar</C1>
<C2>foobar</C2>
</row>
<row>
<C1>foobar</C1>
<C2>foobar</C2>
</row>
<row>
<C1>foobar</C1>
<C2>foobar</C2>
</row>
$ awk '{print} sub(/<C2>.*/,""){print $0"<C3>"++cnt"</C3>"}' file
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>1</C3>
</row>
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>2</C3>
</row>
<row>
<C1>foobar</C1>
<C2>foobar</C2>
<C3>3</C3>
</row>
请注意,数字12和13可以根据您的输入进行调整,它们不需要在脚本中对top进行硬编码,但是如果需要则可以使用idk,因此我不必理会。