我有一个具有不同节点的 xml 文件,我想像这样分割文件:
<unix>
<mm>
</unix>
<osx>
<nn>
</osx>
当我运行脚本时,我希望它生成一个名为 的 xml 文件unix.xml
,其中包含以下内容
<unix
<mm>
</unix>
然后是另一个名为 的 xml 文件osx.xml
,其中包含以下内容
<osx>
<nn>
</osx>
答案1
首先 - 我会说我认为使用 XML 解析器以外的任何东西进行 XML 解析是一个非常糟糕的主意。正则表达式可能看就像它们会起作用一样,但这确实是编写一些脆弱代码的好方法 - 语义上等效的 XML 对于不同的 RE(例如缩进/换行和一元标签)可能看起来不同。
因此考虑到这一点 - 我会使用 Perl 和XML::Twig
库。这是一个非常标准的事情——到处都有预构建的包。
然而,也许最重要的是 - 您发布的 XML 无效。我假设这是因为它是一个示例,而不是真正的 XML,因此您错过了一些内容。我正在使用作为我的样本:
<root>
<unix>
<mm />
</unix>
<osx>
<nn />
</osx>
</root>
使用此代码将满足您的要求:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new( 'pretty_print' => 'indented' );
$twig->parsefile("your_xml.xml");
foreach my $element ( $twig->root->children ) {
my $tag = $element->tag;
print "Processing $tag\n";
#print to STDOUT for debugging
print $element ->sprint;
#print to output file
open( my $output, ">", "$tag.xml" ) or warn $!;
print {$output} $element->sprint;
close($output);
}
当然,如果您发布的 XML 是字面上地如果你拥有什么,那么它就是损坏的 XML,并且理想情况下,你应该去找任何给你它的人,并提供规范文档的卷起副本。如果由于现实生活而这不切实际,那么我会在 Stack Overflow 上为您提供以下答案: https://stackoverflow.com/a/28913945/2566198
答案2
我认为以下内容应该有所帮助。这是通常的任务,应该在两个限制之间完成。
unset f t
while read l
do
t=${t:+$t\\n}$l
l=${l//[<>]/}
: ${f:="$l"}
if [ "$l" = "/$f" ]
then
echo -e "$t" > "$f".xml
unset f t
fi
done < <(cat your_xml_file)
答案3
xml剪切从xml-coreutils可以满足您的需求