- ベストアンサー
指定行データの取得
perlにてテキストファイルのある指定行のデータを取得するのは どのようにするのでしょうか? 行の選択は 「5行目(または5)」のように指定したいと思います。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#1です。 >なにか処理時間を短縮できる、うまいやりかたなどないのでしょうか? まず各行が固定長であるならば seek 関数を使ってファイルポインタを一気に移動させることができます。 例えば一行100バイトと決まっているなら、100バイト×(5-1) の位置へ移動させれば次に読み込むのは5行目ということになります。 (5-1)の意味はファイルポインタの先頭は0なので400バイト目が5行目になります。 各行が固定長でない場合、各行の位置を記録した別のファイルを作ることで高速化させることもできます。 例えば1行目は0、2行目は50、5行目は150、などど記録しておいて、5行目が必要なら150を取り出して先程の seek 関数で移動させる。 ま、これをやるにはその別のファイルの管理も必要になりますが。 ファイル読み込みの高速化は突き詰めればデータベースになってしまいますね。 またperlで扱う程度のファイルサイズ(例えば1000行や10000行程度)なら気にするほど速度は遅くないと思います。 多分コンマ1秒もかからないですよ。 何百万行もある最後のほうの行を取得となると話は別ですが。
その他の回答 (2)
- Tacosan
- ベストアンサー率23% (3656/15482)
$. が読み込んだ行数を覚えているので, 5行目を表示するなら open(IN, "<hoge"); while (<IN>) { print if $. == 5; } でいいんですが, 1000行目を表示するときに 1000行読み込んじゃうのはしょうがないですね. 1000行目ということは「999個目の \n から 1000個目の \n の間」を意味するわけですが, 読み込んだ \n が何個目かを知るには本質的に先頭から読んでいくしかないわけで.
- ttyp03
- ベストアンサー率28% (277/960)
基本的には1行読むという処理を5回やればいいわけです。 $pos = 5; open( IN, "test.txt" ); $line = ""; for( $i = 1; !eof( IN ); $i++ ){ $work = <IN>; if( $i == $pos ){ $line = $work; break; } } close( IN ); print $line; もしくは一括でファイル内容を取り込み、配列から取得することもできます。 ただこの方法ですと、対象となるファイルが巨大だとその分メモリを食うことになるので注意が必要です。 $pos = 5; open( IN, "test.txt" ); @file = <IN>; close( IN ); print $file[$pos - 1];
お礼
回答ありがとうございます。 この方法ですと1000行目を読む場合は1000行分をよまないと いけないのですね。 なにか処理時間を短縮できる、うまいやりかたなどない のでしょうか?