人気マンガがだれでも無料♪電子コミック読み放題!!

以前も質問させていただきましたが、
大量データから抽出する際の効率よいperlプログラム作成について
また、教えてください。
例)
大量データ Aファイル 3列 可変値(数値、URL、数値)タブ区切り 重複値あり
123 http://www.XX.co.jp/XX 4567
1111 http://www.XX.co.jp/XX 3333
3 http://www.XX.co.jp/YZ 4567
1111 http://www.YYY… 116

抽出対象データ Bファイル 1列(URL)重複なし
http://www.XX.co.jp/X
http://www.YYY.co.jp


BファイルにあるURLで始まるURLがAファイルにある場合 Aファイルのその行を抽出したい。
grepで実施すると すごい時間がかかってしまうため、効率よい抽出方法をおしえてください。
今回は、完全一致ではなく、Bファイルに入っているリストのURLから始まるものにしたいと考えているので、前の手法(hash連想配列)が使えないと考えております。
Aファイルが容量大きいため、grep処理では1週間たっても終わらないのです。

このQ&Aに関連する最新のQ&A

A 回答 (9件)

本当に終わるか気になったので、自分のPCで試してみました。


メモリ4Gであれこれ普通に使いながら、次のものです。
ただ、内一個は途中でやめちゃいました。

まず、こんなかんじでdummyファイルを作りました

Ruby
# dummy作成
http://ideone.com/TDxut
→1Gバイトで約2000万件の嘘データ
# フィルタ元リスト作成
→dummyの頭50件の、URL内ドメイン箇所までのリスト

Ruby
# 文字列マッチ
http://ideone.com/xPsku
→約25分

# 正規表現マッチ
http://ideone.com/kvSff
→途中でやめた為不明

GNU/grep
# grep -F -f 元リスト.txt dummy.txt
→1分弱!


ということで、少なくともRubyでは全く太刀打ちできませんでした。
でも、終わる分量ではあると思います。特にPerlならきっともっと早いんでしょう
やっぱりgrepがおすすめですね
    • good
    • 0
この回答へのお礼

処理試してみました。
まだ、2日間perlプログラムを回しても終わらなかったのが、
ほんの数分で完了しました。
プログラム知識がないので、ファイル内容を読み取り grep関数が処理してくれるという方法を知らなかったので、助かりました。
ありがとうございました。

お礼日時:2011/05/12 10:23

#1です。



>今回は、完全一致ではなく、Bファイルに入っているリストのURLから始まるものにしたいと考えているので、前の手法(hash連想配列)が使えないと考えております。

>この方法は Bファイル内のURLと完全一致のものを探すということになりませんでしょうか?

あっそうか。
じゃindex関数使えばいいんじゃないでしょうか。
http://perl.enstimac.fr/perl5.6.1/5.6.1/pod/perl …



open B,”B.txt” or die $!; #タブ区切りなので拡張子を変更
while(<B>) {
 chomp; #改行を取る
 $b_url{$_} = 1; #ハッシュのキーに入れる。値はテキトー

close B;

@b_url = sort keys %b_url;
 #ソートはシュウォーツ変換をすると早くなる。でもこのプログラムここが律速段階ではない

open A,”A.txt” or die $!;
open C,”>X.txt” or die $!;
while(<A>) {
 (undef,$url)=split /¥t/; #2個目の値にしか用はない

 for $b_url(@b_url) {
  #ここは普通の配列サーチなので「番兵」を使ったりすると高速化できる
   if (index($url,$b_url)){
     print C;
     last;
   }
 }

close A; #ファイルハンドルが間違ってた
close C;



Larry Wallによると、組み込みのgrep関数よりもPerlは速いっていうことなんですけど、どうなんでしょうね。
上のプログラムも@b_urlがオンメモリなんでそこそこ速いと思います。
ま、やさしい例ってことで。
    • good
    • 0
この回答へのお礼

index関数というものを利用すればよいということは気がつきませんでした。
これで どのくらいの速度がでるか試してみたいと思います。
ありがとうございます。

お礼日時:2011/05/12 10:28

尻のデータが引っかからないことがわかった。

ちょっと改造。

sub create_index {
  my $sumpling_interval = shift;
  my @splited_lines   = @_;
  my @index       = ();

  for ( my $i = 0; ( $i * $sumpling_interval ) <= $#splited_lines; $i++ ) {
    my $pos = $i * $sumpling_interval;
    push @index, { pos => $pos, url => $splited_lines[$pos]->{url} };
  }

  # indexの尻に番兵を置く
  push @index, { pos => $#splited_lines, url => $splited_lines[$#splited_lines]->{url} };
  return @index;
}
    • good
    • 0

適当。

表示がずれるので空白2文字を全角空白で書いていることに注意

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my $words_file = shift || '/usr/share/dict/words';

my @lines = create_dummy_data( $words_file,
  [ 'google.co.jp', 'yahoo.com', 'bing.jp' ] );
print $#lines, $/;

my @splited_lines = split_lines(@lines);
@splited_lines = sort { $a->{url} cmp $b->{url} } @splited_lines;
my @index    = create_index( 1000, @splited_lines );
my @target_urls = qw(http://google.co.jp/picture http://bing.jp/illust);
my @finded   = find_lines( \@splited_lines, \@index, \@target_urls );

print Dumper($_), $/ for @finded;

sub find_lines {
  my $splited_line_ref = shift;
  my $index_ref    = shift;
  my $target_url_ref  = shift;
  my @finded      = ();

URL_LIST:
  for my $target_url ( @{$target_url_ref} ) {
    my $previous_pos = -1;
    for my $index ( @{$index_ref} ) {
      if ( ( $target_url cmp $index->{url} ) <= 0 ) {
        if (  ( $previous_pos == -1 )
          && ( $target_url cmp $index->{url} ) != 0 )
        {

          # Not found
          next URL_LIST;
        }

        # search first match pos
        my $pos = $previous_pos;
        while ( $splited_line_ref->[$pos]->{url} !~ m/^$target_url/ )
        {
          if ( $pos > $index->{pos} ) {

            # Not found
            next URL_LIST;
          }
          $pos++;
        }

        # founded. push data
        while ( $splited_line_ref->[$pos]->{url} =~ m/^$target_url/ )
        {
          push @finded, $splited_line_ref->[$pos];
          $pos++;
        }
      }
      $previous_pos = $index->{pos};
    }
  }
  return @finded;
}

sub create_index {
  my $sumpling_interval = shift;
  my @splited_lines   = @_;
  my @index       = ();

  for ( my $i = 0; ( $i * $sumpling_interval ) <= $#splited_lines; $i++ ) {
    my $pos = $i * $sumpling_interval;
    push @index, { pos => $pos, url => $splited_lines[$pos]->{url} };
  }
  return @index;
}

sub split_lines {
  my @lines     = @_;
  my @splited_lines = ();

  for my $line (@lines) {
    if ( $line =~ m/(\d+)\s(.+)\s(\d+)/ ) {
      push @splited_lines, { num1 => $1, url => $2, num2 => $3 };
    }
  }
  return @splited_lines;
}

sub create_dummy_data {
  my $file     = shift;
  my $base_url_ref = shift;
  my @lines    = ();

  open my $fh, '<', $file or die "$!:$file";
  while ( my $word = <$fh> ) {
    $word =~ s/\x0D?\x0A?$//;
    for my $base_url ( @{$base_url_ref} ) {
      my $url = 'http://' . $base_url . '/' . $word;
      my $line = '1234' . "\t" . $url . "\t" . '56789';
      push @lines, $line;
    }
  }
  close $fh or die "$!:$file";
  return @lines;
}
    • good
    • 0
この回答へのお礼

プログラムを具体的に書いていただき、ありがとうございます。
しかも、処理を実際に試していただき、確認までありがとうございます。
index関数で考えることに気がつかなかったので、今回 大変勉強になりました。
perlプログラムで処理する場合は これを活用させていただきます。

お礼日時:2011/05/12 10:31

速度が求められていて尚且つUNIX環境なのであれば、


OS添付のgrepコマンドを第一選択肢にすることを自分からもおすすめします。

ただ検索対象にURLが入ってますので、-Fオプションは付けたほうがいいでしょう

grep -f b.txt -F a.txt

のように

<おまけ>
丁度この間同じような処理のワンライナーが話題に出ました。

http://oshiete.goo.ne.jp/qa/6719586.html

ここで書いたワンライナーは、みなさん同様逐次処理です。
awk/Perlはこの手の本家なので、短くかつ早いものが書けるんじゃないかなと思います。
    • good
    • 0

perl プログラムではなく、Linux コマンドの grep を使ってはいかがでしょうか。



grep -f Bファイル Aファイル > extract.txt

で B ファイルの各行を含む Aファイルの行が抽出されます。

grep コマンドは C で書かれているし、そもそも抽出するためのコマンドなので
高速に抽出するための最適化が行われていると期待してもよいのではないでしょうか。

perl での解決ではないので反則かな。
    • good
    • 0

index を使ってみましたが、どの程度時間がかかるはわかりません。



use strict;
my @search;
open IN, "B" or die "Can't open B: $!";

while (my $line = <IN>) {
chomp $line;
push @search, $line;
}

open IN, "A" or die "Can't open A: $!";

while (my $line = <IN>) {
foreach my $search (@search) {
if (index($line, $search) > -1) {
print $line;
last;
}
}
}
    • good
    • 0
この回答へのお礼

indexを利用することを教えていただき、ありがとうございます。
index処理を試してみたいと思います。

お礼日時:2011/05/12 10:34

こんばんは



>大量データから抽出する
これは、SQL(データベースに使う言語)が得意とするところです。
可能ならば、SQLで処理できるようにする方が、Parlの中だけで行うより簡単かつ高速になると思います。

補足要求です
1.レコードの数(データの行数)はどれくらいですか?(数万、数十万など、桁を教えてください)
2.手元にあるパソコン等で行いますか?それとも、Web上で行いますか?

この回答への補足

回答ありがとうございます。
SQL利用ではなく、プログラム処理での方法ができればしりたく、
ご助言は 感謝いたしますが、grepではないよい方法がありましたら 教えてください。
レコードは 数千万行ほどです。
サーバ上で、直にプログラムをたたくつもりでおります。

補足日時:2011/05/11 13:22
    • good
    • 0

Perlですからもっとうまい人が書けばもっとカッコよくなるかどうかわからないんですが・・・。



open B,”B.csv” or die $!;
while(<B>) {
 chomp; #改行を取る
 $B{$_} = 1; #ハッシュのキーに入れる。値はテキトー

close B;

open A,”A.csv” or die $!;
open C,”>X.csv” or die $!;
while(<A>) {
 (undef,$url)=split /¥t/; #2個目の値にしか用はない
 print C if $B{$url}; #$urlがハッシュ%Bのキーとして存在すれば1を返すので真

close B;
close C;

早く終わるかどうかわかりません。
どっちもソートしてよかったらもっと早くなるかもしれないけど・・・。

この回答への補足

回答ありがとうございます。
この方法は Bファイル内のURLと完全一致のものを探すということになりませんでしょうか?

補足日時:2011/05/11 12:00
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QPerlで特定行から特定行までを抜き出したい

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

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

example.log
==================================
aaaa
hogehoge
test
okok
perl
script
==================================

上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。
イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

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

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

Aベストアンサー

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $flag = 0 }
  elsif ($flag) { print "$data\n" }
}
close FH;

で、もっと略したいPerlな人だとこんな感じ。Perl独特の記法がふんだんに使われているので、勉強するには不向きかもしれませんが^^;

open FH, "example.log" or die $!;
while (<FH>) {
  print if /^hogehoge$/ .. /^perl$/ and !/^(?:hogehoge|perl)$/;
}
close FH;

※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $fl...続きを読む

QPerlで別ファイルから文字列の抽出

当方、サーバ管理でインフラ系の経験しかなく、今回はperlでスクリプトの作成に挑戦しておりますがなかなか理解できていません。お知恵をお貸しください。

やりたいこと:
ある入力を受けたら、別ファイルに照会して特定列の文字列を抽出する。以下に例を示します。

入力が gad の場合(小文字です)、file1を参照する。例では一行目にGAD****があるのでこれに該当することとする。最終的にoffice が出力されるようにしたい。


file1の内容:
GAD93911 <test1> office
HOA14845 <test2> desk
ABC52311 <test3> chair
KFI33823 <test4> home

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

Aベストアンサー

ファイルを開いて、各行を順番に /$in\d+\s<\w+>\s(\w+)/iでマッチするものを取り出して、それを使う・・

Qperlで大容量CSVのsort方法について

perlで大容量CSVのsort方法について


perlでcsvファイル100MB超のファイルをソートしたいと思ってますが、以下の方法でメモリーの関係上(と思ってます。)できません。

ソートを行う方法がありますでしょうか?
件数も11万件あるので、エクセルでソートしてからの受け渡しが出来ずに悩んでます。

(ここから)
#sortロジック
sub sort {
use warnings;
use feature ':5.10';

open my $ifh, '<', $inport or &error("Can't open $inport");
my @lines = <$ifh>;
close $ifh;

print @lines, "\n";
#csvファイル何番目?

my @sorted = map { $_->[0] }
sort { $b->[0] <=> $a->[0]}
map { [(split q{,}, $_)[0], $_] }
@lines;

@lines = @sorted;
exit;
}
(ここまで)

いつも貴重なアドバイスをありがとうございます。よろしくお願いいたします。

perlで大容量CSVのsort方法について


perlでcsvファイル100MB超のファイルをソートしたいと思ってますが、以下の方法でメモリーの関係上(と思ってます。)できません。

ソートを行う方法がありますでしょうか?
件数も11万件あるので、エクセルでソートしてからの受け渡しが出来ずに悩んでます。

(ここから)
#sortロジック
sub sort {
use warnings;
use feature ':5.10';

open my $ifh, '<', $inport or &error("Can't open $inport");
my @lines = <$ifh>;
close $ifh;

print @lines, "\n";
#csvファイル何番...続きを読む

Aベストアンサー

ファイルを1度に読み込まずに、while ループで読み込んでソートキーをハッシュのキーに割り当て、ハッシュの配列に保存して、一定数になったらファイルに保存して、最後にまとめればそれほどメモリは必要ないと思います。

my %sorted;

while (my $line = <$fh>) {
my $key = (split /,/, $line)[0];
push @{$sorted{$key}}, $line;
if (@{$sorted{$key}} == 1000) {
open OUT, ">>$key.tmp" or die "Can't open: $!";
print OUT @{$sorted{$key}};
close OUT;
@{$sorted{$key}} = ();
}
}

open OUT, ">out.txt" or die "Can't open: $!";
foreach my $key (sort { $b <=> $a } keys $sorted) {
if (-e "$key.tmp") {
open IN, "$key.tmp" or die "Can't open: $!";
print OUT while <IN>;
close IN;
}
print OUT @{$sorted{$key}} if @{$sorted{$key}};
}
close OUT;

ファイルを1度に読み込まずに、while ループで読み込んでソートキーをハッシュのキーに割り当て、ハッシュの配列に保存して、一定数になったらファイルに保存して、最後にまとめればそれほどメモリは必要ないと思います。

my %sorted;

while (my $line = <$fh>) {
my $key = (split /,/, $line)[0];
push @{$sorted{$key}}, $line;
if (@{$sorted{$key}} == 1000) {
open OUT, ">>$key.tmp" or die "Can't open: $!";
print OUT @{$sorted{$key}};
close OUT;
@{$sorted{$key}} = ();
...続きを読む

Q数値かどうかの判定方法

$aに代入されているものが数値かどうかを判定するにはどのようにしたらよいのでしょうか?

Aベストアンサー

$a =~ /^[0-9]*$/
上記の場合、*は「直前のパターンの0回以上の繰り返し」の意味なので、0から9がなくても、つまり$aが空でもマッチしてしまいます。
なので、
$a =~ /^[0-9]+$/
としましょう。
(+は「直前のパターンの1回以上の繰り返し」)
また、0-9は\dで表すこともできるので
$a =~ /^\d+$/
と書くこともできます。

Q高速に文字列の比較

高速に文字列の比較

open(IN,"$file");
while (<IN>) {
my($ip,$flag) = split(/,/,$_);
if($flag==1){$data .= "$ip,";}
}
close(IN);

open(IN,"$file2");
while (<IN>) {
my($ip,$x,$z) = split(/,/,$_);
foreach ( split(/,/, $data) ) {
if ($ip eq $_) {$xdata.= "$ip,$x,$z\n";}
}
close(IN);


1.$fileで、$flagが1なら$ipを変数$dataに加えます。
2.$file2の$ipが、$dataの$ipに含まれていれば,$file2のデーターを$xdataに加えます。

上記の書き方で一応比較は出来ているようなのですが、perlの知識があまりない素人が適当に考えた書き方なので、自信がありません。
$data .= "$ip,";の$ipの後ろに,を入れている部分も何だか変なのですが、他の書き方が思いつけません。

書き方が間違っている場合や、こうすればもっと高速に動作させられるという書き方があれば、ご指導いただけると幸いです。
$fileも$file2も、100万行あたりまで増える見込みなので、出来るだけサーバーに負荷のかからない書き方ができればと思っています。
お手数ですが、どうぞよろしくお願いいたします。

高速に文字列の比較

open(IN,"$file");
while (<IN>) {
my($ip,$flag) = split(/,/,$_);
if($flag==1){$data .= "$ip,";}
}
close(IN);

open(IN,"$file2");
while (<IN>) {
my($ip,$x,$z) = split(/,/,$_);
foreach ( split(/,/, $data) ) {
if ($ip eq $_) {$xdata.= "$ip,$x,$z\n";}
}
close(IN);


1.$fileで、$flagが1なら$ipを変数$dataに加えます。
2.$file2の$ipが、$dataの$ipに含まれていれば,$file2のデーターを$xdataに加えます。

上記の書き方で一応比較は出来ているようなのですが、perlの知...続きを読む

Aベストアンサー

一応「配列なりハッシュなり」と書いたんだけど, 「たくさんの文字列と等しいかどうか比較する」ときには戦略の 1つとして「比較対象となる文字列をキーに持つハッシュを使う」ことがあります. たとえば, 前半のループを
while (<IN>) {
my($ip,$flag) = split(/,/,$_);
if ($flag == 1) { $data{$ip} = 1; }
}
として, 比較対象の文字列をハッシュ %data のキーに入れます. すると後半は
while (<IN>) {
my($ip,$x,$z) = split(/,/,$_);
if (defined $data{$ip}) {$xdata.= "$ip,$x,$z\n";}
}
とでき, foreach ループをまるまる消し去ることができてしまいます.
この辺はメモリとのトレードオフにもなるので, 何を優先するかによってどうするかが決まります.
ちなみに前半のループで文字列を配列 @data に入れたときは, 後半のループ中
foreach ( split(/,/, $data) )
のところが
foreach (@data)
のようになります.
ところで, 最終的に $xdata をどうするの? これも, 場合によっては配列にする方がいいかも.

一応「配列なりハッシュなり」と書いたんだけど, 「たくさんの文字列と等しいかどうか比較する」ときには戦略の 1つとして「比較対象となる文字列をキーに持つハッシュを使う」ことがあります. たとえば, 前半のループを
while (<IN>) {
my($ip,$flag) = split(/,/,$_);
if ($flag == 1) { $data{$ip} = 1; }
}
として, 比較対象の文字列をハッシュ %data のキーに入れます. すると後半は
while (<IN>) {
my($ip,$x,$z) = split(/,/,$_);
if (defined $data{$ip}) {$xdata.= "$ip,$x,$z\n";}
}
とでき, foreach ル...続きを読む

Q複数ファイルの読み込みについて

perl初心者です。

あるディレクトリから拡張子がdataであるファイルを全て読み込みたいのですが、方法がわかりません。
cshで書くと
foreach arg (*.data)
コマンド $arg

のようになりますが、perlだと
foreach $arg (@arg){
コマンド $arg

となりますよね?
引数がリストなのでよくわかりません。
そもそもperlではできないのでしょうか?


それともう一点ですが、ファイルオープンするときに
foreachループの中で
open(FILE, "$arg");
とすることは可能ですか?
上の質問と組み合わせて全てのファイルを開いて作業を行いたいので。

説明が下手ですいません。補足しますのでよろしくお願いします。

Aベストアンサー

while(<*.data>)
{
## $_には、*.DATAなファイル名が格納されている。
open(F,"$_"); ##openする。
while(<F>)
{
##読み出された内容が$_に格納されている。
print $_; ##出力してみる。
}
}

というのが最短コーディングです。

QPerlで変数を使用した置換ができない

ファイル内の「1 2 3 4 5」などの数字の箇所を、「1回 2回 3回 4回 5回」のように、「回」をつけた形に変えることを考えています。
以下のようなスクリプトを書きましたが、うまくいきません。

# 「$search_replace」の参照先のテキストファイルの内容
(\d) タブ記号 $1回


EOF

# 問題のスクリプト(一部)
chomp($search_replace);
(my $search, my $replace) = split(/\t/, $search_replace);
$string[$i+1] =~ s/$search/$replace/g; #ここが問題と思われる箇所

ほしい結果は右のとおり。「1回 2回 3回 4回 5回」
現実の結果は右のとおり。「$1回 $1回 $1回 $1回 $1回」

置換文字列の$1の部分がうまく展開(?)できないようです。
どうすればよいか、ご教示ください。

Aベストアンサー

正規表現の置換部はダブルクォート文字列と同様に評価されるので、次の2つの文は同じように機能します。質問のケースでは、変数を2重に置き換えなければならないので、明示的にダブルクォートが必要になります。

$string[$i+1] =~ s/$search/$1回/g;
$string[$i+1] =~ s/$search/"$1回"/eg;

Qテキストファイルの高速な読み込みは?

1つのテキストファイル(5~10KB)を一度に変数に読み込むために、

open(IN, $file);
my $data = join('',<IN>);
close(IN);

と、

my $data;
open(IN, $file);
while(<IN>){ $data .= $_ }
close(IN);

の2つを比較していたのですが、自分がベンチマークをとった限りでは後者の方が速いみたいです。これより早い方法はないでしょうか?

Aベストアンサー

$/=undef;
my $data;
open(IN, $file);
$data=<IN>;
close(IN);
かなあ

Qファイルの行数取得

超初心者です。

いま、表計算的なスクリプトを記述しています。

あるファイルの行数を取得する関数ってあるんでしょうか?

ファイルに記述されている数値を足したり引いたりするのですが、forを使っての計算の際にファイルの行数が必要となりました。

Aベストアンサー

Perlにですね。ないはずです。
行数とはファイルに書かれた改行文字の個数ということなので
実際にファイルを全て読み込まないと行数はわかりません。
以下のように色々な方法があると思います

#### 単純な例
$a = 0;
open FD, "<file.txt" || die $!;
while (<FD>) {
$a++;
}
close FD;
print "行数:$a\n";

### 少しマニアックな方法
open FD, "<file.txt" || die $!;
@a = <FD>;
close FD;
print "行数:" . ($#a + 1) + "\n";


### 反則的方法(外部コマンド) ... UNIXの場合
print "行数:" . `wc -l file.txt` . "\n";

QUse of uninitialized value ---

初心者です。フォームに文字を入力してもらい、↓
print blockquote(
textfield(
-name => 'die Antwort',
省略----条件にあえば、
my $value = param('die Antwort');#として
if (($value eq $ans || $value eq $ans2) and ($c eq $num)){
「正解」と表示することにしました。すると、うまくいくのですが、
if (($value eq $ans || $value eq $ans2) and ($c eq $num)){
について「Use of uninitialized value ----」とApacheのerror logに書かれてしまいます。このためerror logがすぐに巨大なファイルになってしまいます。これを避ける方法をお教えください。よろしく、お願いいたします。

Aベストアンサー

コードに use warnings が入っているのですよね。
デバッグも済んでいるのでしたら、
no warnings qw ( uninitialized );
で、この警告の表示を抑制してもよいと思います。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング