![使用 sed/awk 解析 XML 标签](https://linux22.com/image/1366572/%E4%BD%BF%E7%94%A8%20sed%2Fawk%20%E8%A7%A3%E6%9E%90%20XML%20%E6%A0%87%E7%AD%BE.png)
顺便说一下,我花了好几天的时间来处理这个问题,但没有成功。
我正在处理包含以下内容的数据的 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
如果您正在寻找具有相同name
AND 的行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_id
、name
和group_id
,它们分别保存为$1
、$2
和$3
。push @{$k{join("\t",$2,$3)}},$1;
:这有点复杂。它创建一个名为 (%k
) 的数组哈希,然后使用制表符join
连接name
和。最后,它将添加到数组中。换句话说,如果你的是,你的是,你的是,这将创建一个数组并将其保存为键的哈希值。group_id
row_id
row_id
123
name
456
group_id
789
%k
456 789
END{}
当文件的其余部分处理完毕后,该块将执行一次。它将遍历哈希的每个键(其值是数组),并打印出数组中有多个条目的情况,换句话说,就是重复项。该pop
函数返回数组的最后一个元素,在本例中为row_id
。
我根据您的示例运行了这个程序并得到了以下输出:
4022 67581916031 306643757002
---- ---------- ------------
| | |---------------> row id
| |---------------------------> group id
|---------------------------------------> name
如果你没有看到第二点中的链接,我只想强调一下你绝不应该用正则表达式来解析 [X]HTML。
答案2
不言而喻,使用正则表达式无法安全地解析 XML。您需要一个 XML 解析器。
你能解析已知的 XML 子集,但在实践中这通常比学习使用 XML 解析器要困难得多。