プロが教えるわが家の防犯対策術!

皆さんのお知恵をお貸し頂ければ幸いです。

Perlで以下のようなことをしたいと考えています。
例えば、次のようなテキストファイルがあったとします。

example.log
==================================
aaaa
bbbb START
hogehoge
cccc START
test
okok
perl
eeee END
script
==================================

上記ファイルを読み込んで、「cccc START」から「eeee END」の間に挟まれた行だけ抜き出したいのです。
いろいろ試してみましたが、どうしても初めの「bbbb START」から「eeee END」まで出力されてしまいます。

このような場合、どういう風にすればいいのでしょうか?
恐れ入りますが、ご教授頂ければ幸いです。

それでは、どうぞよろしくお願い致します。

A 回答 (4件)

foreach (<>) {


if(/\bSTART$/){$f=1,$x=""}
elsif($f && /\bEND$/){print $x;$f=0}
elsif($f){$x.=$_}
}
    • good
    • 0

本当に


「cccc START」から「eeee END」の間
であるなら, しかるべく指定すれば
どうしても初めの「bbbb START」から「eeee END」まで出力されてしまいます
なんてことにはならないよ.

さておき, #2 と同じ方針だけどたとえば
open my $fh, '<', 'example.txt' or die "file open error\n";
$_ = do {
local $/ = undef;
<$fh>;
};
my ($target) = m/.*\sSTART$(.*)\n[^\n]*\sEND$/ms;
print "$target\n";
とか?
    • good
    • 0

こんな感じ?



my $str = "";
my $ret = "";
open(DATAFILE, "< example.log") or die("error :$!");
while (my $line = <DATAFILE>){
chomp($line);
$str = "$str$line\n";
}
close DATAFILE;
if ($str =~ /cccc START([\s\S]+)eeee END/){
$ret = $1;
}
print "$ret";
    • good
    • 0

STARTの次の行から出力ではなく、内部にためるようにしないとだめです。


ためている最中にSTARTがきたら、いままでためていたのを破棄します。
ENDがきたら、たまっていたもの吐き出します。

open(INFILE,"example.log");
@lines = ();
$flag = 0;
while(<INFILE>){
if ($_ =~ m/\sSTART$/){
$flag = 1;
@lines = ();
next;
}
if ($flag == 1){
if ($_ =~ m/\sEND$/){
$flag = 0;
&flush();
next;
}
push(@lines,$_);
}
}
close INFILE;

sub flush()
{
foreach $line (@lines){
print $line;
}
@lines = ();
}
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!