使用 sed/awk 解析 XML 标签

使用 sed/awk 解析 XML 标签

顺便说一下,我花了好几天的时间来处理这个问题,但没有成功。

我正在处理包含以下内容的数据的 XML 文件:

<row id="67581917031" name="4022" filesize="22425" file_content_id="67581868031" lastmodify_datetime="1187126570050" group_id="67581916031"/> <row id="254115371041" name="4022" filesize="49471" file_content_id="254115361041" lastmodify_datetime="1220512827666" group_id="253405951041"/> <row id="286104505041" name="4022" filesize="3802672" file_content_id="286104455041" lastmodify_datetime="1223348052489" group_id="286104504041"/> <row id="289541609041" name="4022" filesize="42235" file_content_id="264826268041" lastmodify_datetime="1223587308419" group_id="289541607041"/> <row id="306643757002" name="4022" filesize="392560" file_content_id="243411753011" lastmodify_datetime="1218251898489" group_id="67581916031"/> <row id="367316910041" name="4022" filesize="381083" file_content_id="367316830041" lastmodify_datetime="1232592570004" group_id="74169006021"/>

如果仔细查看,您会发现其中两条记录具有相同的“名称”和“group_id”。我正在尝试编写一个脚本,该脚本将查找这些行并输出相应的行 ID、名称和 group_id。我希望做的是使用 sed 拾取每“行”的末尾并插入换行符 (\n),然后我可以使用nl打印出行数,将该数字存储在变量中,然后使用 for 循环运行 awk 命令以对每行 id、名称和 group_id 进行模式匹配,并以某种方式检查名称和 group_id 是否与任何其他行匹配,如果匹配,则打印出行 id 和名称。

答案1

如果您正在寻找具有相同nameAND 的行group_id,您可以执行以下操作(假设您在 *nix 操作系统上,您没有在问题中说明,您可以直接将其粘贴到命令行):

sed 's#/>#/>\n#g' simple_file.xml |
        perl -ne 'if(/row id=.(.+?)\".+name=.(.+?)\".+group_id=.(.+?)\"/){ 
         push @{$k{join("\t",$2,$3)}},$1;} 
         END{ 
           foreach (keys(%k)){ 
            if($#{$k{$_}}>0){
                 print "$_\t",pop @{$k{$_}},"\n" 
          } }}' 

解释:

  • sed 's#/>#/>\n#g' simple_file.xml:在每个条目之后(每个之后)添加一个换行符,/>以方便解析。
  • perl -ne:逐行处理文件
  • /row id= ... group_id=.(\d+)/;:使用正则表达式(通常是馊主意对于 [X]HTML 文件,你手上可能沾满了小猫的血)得到 row_idnamegroup_id,它们分别保存为$1$2$3
  • push @{$k{join("\t",$2,$3)}},$1;:这有点复杂。它创建一个名为 ( %k) 的数组哈希,然后使用制表符join连接name和。最后,它将添加到数组中。换句话说,如果你的是,你的是,你的是,这将创建一个数组并将其保存为键的哈希值。group_idrow_idrow_id123name456group_id789%k456 789

  • END{}当文件的其余部分处理完毕后,该块将执行一次。它将遍历哈希的每个键(其值是数组),并打印出数组中有多个条目的情况,换句话说,就是重复项。该pop函数返回数组的最后一个元素,在本例中为row_id

我根据您的示例运行了这个程序并得到了以下输出:

4022    67581916031 306643757002
----    ----------  ------------
 |           |           |---------------> row id
 |           |---------------------------> group id
 |---------------------------------------> name

如果你没有看到第二点中的链接,我只想强调一下你绝不应该用正则表达式来解析 [X]HTML。

答案2

不言而喻,使用正则表达式无法安全地解析 XML。您需要一个 XML 解析器。

解析已知的 XML 子集,但在实践中这通常比学习使用 XML 解析器要困难得多。

相关内容