まず、入力が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> cat s1.txt
ここにたくさんのテキスト
ここにたくさんのテキスト
ここにたくさんのテキスト
C:\ Temp> cat s2.txt
ここにもう少し
ここにもう少し
ここにもう少し