電子書籍の厳選無料作品が豊富!

お世話になります。

perlを使用して、
下記の元ファイル[infile.txt]よりstart~endの範囲を各テキストファイルに
分割出力する方法をご教授いただけないでしょうか。

 ※出力ファイル名は元のファイル名 (infile) + 1行目の文字列(単語)にします。
  例>>infile_1111.txt , infile_333.txt

よろしくお願いいたします。

[infile.txt]
aaaa
bbbb
start
1111
2222
end
dddd
eeee
start
3333
4444
end

A 回答 (4件)

エラーの理由を感違いしていました。

以下、訂正します。

(1)
start
end

(2)
start
1111end
start2222
end

実際の処理対象に上記 (1) のような中身のないブロックがある、(2) のような中身の行に start または end 含まれている、ということが考えられます。

(1) の場合は書き出す行がないので無視し、(2) の場合は正常に処理されるようにプログラムを修正してみました。

use strict;
my @content;

while (<DATA>) {
if (/^start$/ .. /^end$/) {
chomp;
push @content, $_ if !/^start$/ and !/^end$/;
if (/^end$/ and @content) {
print "infile_$content[0].txt\n", join("\n", @content), "\n\n";
# open OUT, ">infile_$content[0].txt" or die "Can't open: $!";
# print OUT join("\n", @content), "\n";
# close OUT;
@content = ();
}
}
}

__DATA__
aaaa
start
end
bbbb
start
1111end
start2222
end
dddd
eeee
start
3333
4444
end
    • good
    • 1

<DATA> の後ろの閉じ括弧を忘れました。

すみません。

use strict;
my @content;

while (<DATA>) {
.....
    • good
    • 0

プログラムの冒頭を次のように変更すると、エラーが解消すると思います。



use strict;
my @content;

while (<DATA> {
.....
    • good
    • 0

スカラーコンテキストの範囲演算子を使うのが、一番簡単かと思います。

次のプログラムでは、ファイル名も中身も画面に表示するようになっています。コメントアウトしてある3行を生かすと、ファイルにも書き出すようになります。

while (<DATA>) {
if (/start/ .. /end/) {
chomp;
push @content, $_ if !/start/ and !/end/;
if (/end/) {
print "infile_$content[0].txt\n", join("\n", @content), "\n\n";
# open OUT, ">infile_$content[0].txt" or die "Can't open: $!";
# print OUT join("\n", @content), "\n";
# close OUT;
@content = ();
}
}
}

__DATA__
aaaa
bbbb
start
1111
2222
end
dddd
eeee
start
3333
4444
end

この回答への補足

ご回答ありがとうございます。
初心者で(/start/ .. /end/)の使い方がわからず悩んでました。

line9/10で下記のエラーが出てきたのですが、$contentの初期化をしても解消できませんでした。
Use of uninitialized value $content[0] in concatenation (.) or string at split.pl....

すみませんがよろしくお願いいたします。

補足日時:2011/01/16 12:30
    • good
    • 0

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