首先,如果您要忽略输入是 XML 的事实,那么就不需要 Perl 或 Python 或 gawk 或任何其他语言。只需使用
$ grep '<s1>' input_file > s1.txt
$ grep '<s2>' input_file > s2.txt
并完成它。这似乎效率低下,但考虑到编写脚本然后调用它所花费的时间,效率低下是微不足道的。更糟糕的是,如果您不知道如何编写那个特别简单的脚本,您必须在 SO 上发布并等待一个答案,该答案比grep
解决方案的低效率高出许多许多数量级。
现在,如果输入是 XML 的事实一点也不重要,那么您应该使用 XML 解析器。与elsethread 的错误声明相反,有很多 XML 解析器不必将整个文件加载到内存中。这样的解析器将具有可扩展和正确的优点。
我在下面给出的示例旨在复制您已经接受的答案的结构,以向您展示使用正确的解决方案并不复杂。
只是为了给出公平的警告,下面的脚本可能是最慢的方法。我写它是为了完全模仿公认的解决方案。
#!/usr/bin/perl
use strict; use warnings;
use autodie;
my %fh = map { open my $f, '>', $_; $_ => $f } qw{ s1.txt s2.txt };
use HTML::TokeParser::Simple;
my $parser = HTML::TokeParser::Simple->new(\*DATA);
$parser->xml_mode(1);
while ( my $tag = $parser->get_tag('s1', 's2') ) {
my $type = $tag->get_tag;
my $text = $parser->get_text("/$type");
print { $fh{"$type.txt"} } $text, "\n";
}
__DATA__
<link type="1-1" xtargets="1;1">
<s1>bunch of text here</s1>
<s2>some more here</s2>
</link>
<link type="1-1" xtargets="1;1">
<s1>bunch of text here</s1>
<s2>some more here</s2>
</link>
<link type="1-1" xtargets="1;1">
<s1>bunch of text here</s1>
<s2>some more here</s2>
</link>
输出:
C:\Temp> 猫 s1.txt
一堆文字在这里
一堆文字在这里
一堆文字在这里
C:\Temp> 猫 s2.txt
这里还有一些
这里还有一些
这里还有一些