• 締切済み

perl初心者です。宜しくお願い致します。

ファイルの容量が大きく。perlを使用してデータの集計をしています。 "A"がきたらflag1をたてなさい。 "B"がきたらflag2をたてなさい。 "C"がきたらflag3をたてなさい。 これでAとBとCを抜き取ること&AからCまでの時間を取得したのですが、 Bの数のmaxの値だけを抜き取りたいのですが、Bがきたときの数をすべて 出力してしまいます。下記の文だと、Bが4回きたら、1,2,3,4と出力してしまいます。 それで4だけを出力したいのですがどのように書き換えたらようか教えて頂けますでしょうか。 '----------------------------------------------------------------------------- open (IN,"< $ARGV[0].txt") or die; open (OUT,"> $ARGV[0]_out.txt") or die; $flag =0; my $a, $b, $c; $count = 0; ####################################################### while($line =<IN>){ ($time,$data) = split(/\s+/,$line); if($data eq "A") { $flag=1; $a = $time; #print OUT $line; #print OUT "\n"; } elsif($data eq "B"){ $flag=2; $count++; $count == $data; print OUT ("$count\n") } #print OUT ("$count\n"); elsif($data eq "C"){ $flag=0; $count=0; $b = $time; $c = $b - $a; print OUT ("time $c\n") } } -------------------------------------------------------------------------------

  • Perl
  • 回答数6
  • ありがとう数0

みんなの回答

  • yamada11
  • ベストアンサー率18% (2/11)
回答No.6

出力していって書き込みたいって意味でしたか・・・。よく理解して無かったです。すいません。 もしBをみつけた最大の時に書き込みたいなら、まずBの個数をいったん調べる必要があると思います。 私ならそうするって程度意見ですが。

  • yamada11
  • ベストアンサー率18% (2/11)
回答No.5

自分だったら、Bの$countを$count_b(グローバルに宣言して)とかにして、while文抜けた後に出力するかな。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

や~, そこまでは言ってませんよ~>#3. そもそも「何を考えてこのプログラムを作ったのか」がさっぱりわからんので.... 例えば elsif($data eq "C") のところで $count を 0 にする理由が見当たらん. 「flag1 をたてる」が $flag = 1; で「flag2 をたてる」が $flag = 2; なのになぜ「flag3 をたてる」が $flag = 0; になるのかとか, とにかく上の文章からどうしてこんなプログラムになるのかわからんのですよ....

回答No.3

次のようにするとどうでしょうか。 No.1さんが言ってるのは 2 のことですよ。 1. eq 'B'節の $count == $data; は無駄なので削除 2. eq 'B'節の print を eq 'C'節の $count = 0; の行より前に移動 3. eq 'C'節の $b は無駄なので削除して、$c = $time - $a; とする

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

どう「だめだった」のかを明らかにするつもりはないんでしょうか?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

最後に出力すれば?

kousuke_1230
質問者

補足

最後に出力すればいいと思い、print OUT ("$count\n"); をうしろにもってきてもだめでした。

関連するQ&A

  • 元号判定:Perl初心者です

    Perlにおいて、「元号を判定させる」ようにしたく、if-elsif文章を書いてみたのですが、上手くいきません。 (そもそも起動してくれないです・・・文章も合っているかわからないのですが。。) 年号を入力させて、 (meizi) X nenと表示させたいのです。 あと、明治以前の数字を入れたら、エラーと出すようにする。 被っている年号、例えば1912年と入れたら、meizi45nen/taisyou1nen ともしたいのですが、これらはどう入れたらいいのか分からなかったです。 どこを直せばいいのか、一部でもいいので、教えていただけると嬉しいです。 chomp($year = <stdin>); if($year<=1912 and $year>=1868){ $A=$year-1867 print("meizi $A nen \n"); } elsif($year<=1926 and $year>=1912){ $B=$year-1911 print("taisyou $B nen \n"); } elsif($year<=1989 and $year>=1926){ $C=$year-1925 print("syouwa $C nen \n"); } elsif($year>=1989){ $D=$year-1988 print("heisei $D nen \n"); }

    • ベストアンサー
    • Perl
  • Perlでのforeach文の挙動がわかりません

    Perlに詳しい方教えてください。 WinXP(SP3)+ActivePerl-5.10.0.1004の環境で、重複データのチェックプログラムを 作成していますが、foreach文の挙動がよく分かりませんので教えてください。 ※Perlは独学です。 <入力ファイル> あいうえお あいうえお かきくけこ あいうえお <出力期待値その1> あいうえお,重複しています あいうえお,重複しています かきくけこ あいうえお,重複しています <出力期待値その2> あいうえお,重複しています あいうえお,重複しています かきくけこ あいうえお <プログラムの要約> open(IN,$input_file); # 入力ファイルを読み込み @BASE = <IN>; close(IN); @BASE_2 = @BASE ; # 配列のコピーを作成 $count_1 = '0' ; foreach $data_1 (@BASE) {   $count_1++ ; # 何行目を処理しているかのカウンター   $flag_1 = '0' ; # フラグの初期化   $count_2 = '0' ;   foreach $data_2 (@BASE) { # ←★ここの記述方法の質問です★     $count_2++ ;     if ( $count_1 == $count_2 ) { next; } # 自分自身の行とは比較しない     if ( $data_1 eq $data_2 ) { $flag_1 = '1' ; } # 一致したらフラグを立てる   }      if ( $flag_1 == '0' ) { # フラグが立たなかったらそのまま新しい配列へ追加     push(@kekka,$data_1);   } else { # フラグが立ったらコメントを追加して新しい配列へ     $data_1 =~ s/\n//g;     $data_3 = $data_1 . ",重複しています\n" ;     push(@kekka,$data_3);   } } $kekka_2 = join("",@kekka) ; # 配列のデリミタ対策 open(OUT,"> $output_file"); print OUT "$kekka_2"; close(OUT); exit; <質問> 上記プログラムの★マークの箇所で、 foreach $data_2 (@BASE_2) としますと、<出力期待値その1>が得られます そして、 foreach $data_2 (@BASE) としますと、<出力期待値その2>が得られます プログラムの途中で @BASE_2 = @BASE としていますので、一見しますと 同じ処理をしているように感じるのですけれども、実際には出力結果が異なり ますので、何かが違うのだと思います。 その違いを教えて戴きたいです。 ※投稿確認画面でTABが消えてしまいますのでTABは全角スペースに変更して  おります。  見えづらい場合には申し訳ありません

    • ベストアンサー
    • Perl
  • perl 初心者です。 わかりやすくお願いします。

    Perlを始めたのですが、本や色いろんなサイトを見てもよく分かりません。 Aと言うデータを読み込んで最大最小・平均・標準偏差を求めたいです。 (1)どこが間違っているのか1部づつでもいいので詳しく教えてください。 (2)一つ一つの意味がちゃんとはつかめていないと感じるので流れを教えてください。 #!/usr/bin/perl # 12345 STDIN use strict; use warnings; open ( FILEHANDLE , " < A " ) ; my @Str=<STDIN>; foreach my $Row (@Str ){ print $Row; } my $Minimum=$ARGV[0]; my $Maximum=$Minimum; my $Sum=$Minimum; my $temp=0; my $i=1; while ( $i < $Num_arg){ $temp=$ARGV[$i]; if ( $Minimum > $temp ) { $Minimum = $temp; }elsif ( $Maximum < $temp ){ $Maximum = $temp; } $Sum = $Sum + $temp; $i++; } my $Average = $Sum / $Num_arg; my $w = foreach my $w(0..$#Numbers){ ($Num_arg - $Average) ** / Num_arg; } my $Standarddivitation = sqrt ($w); print "Average value = $Average \n"; print "Maximum Value = $Maximum \n"; print "Minimum Value = $Minimum \n"; print "Standard devitation = $Standarddevitation;

  • perlの制御文について

    汚くて申し訳ありません。 以下のようなperlのプログラムを組んだのですが制御文が思い通りに動きません。 比較対象の数字の先頭の0を取れば正常に動くのですがどうしても0をはずすことはできないのです。 いろいろ試してみたのですがどうしてもうまきかないので知恵を貸してください。 $input = <STDIN>; if($input > 0130){ print "A\n"; } elsif(($input > 0120)&&($input < 0130)){ print "B\n"; } else{ print "C\n"; }

  • perl初心者です。わかる方お願いします。

    DNA情報の解析でDNAに含まれる各塩基の数をカウントするperlプログラムを作りたいのですが、やり方が分りません。以下のような配列があったとして、 ATGCATGCATGCATGCATGCATGCAT このとき、A 7,T 7,G 6,C 6と出力されるようにしたいです。 次のようなperlを作ってみたのですが、 my(@bases, %count, $base); @bases = <>; foreach $base (@bases){ $count{$base} += 1; } foreach $base (keys %count){ print "$base $count{$base}.\n"; } この場合、@basesに入るのは元の1文なので上手く動かないと思うので、元の1文を1文字ずつ行に入れるといけると思うのですが、やり方がわからなくて困ってます。 助けてください。

    • ベストアンサー
    • Perl
  • perlですが疑問がでました

    # 変数$aに1を代入せよ。 $a=1; # もし変数$aが1でなかったら A を表示せよ。 # もしくは変数$aが2でなかったら B を表示せよ。 # どれも真の場合は C を表示せよ。 unless($a==1){ print "A"; }elsif($a==2){ print "B"; }else{ print "C"; } とあって結果はCと出ます。私てきにはBが表示されるのかなと思ったのですが違いました。なぜCが表示されるのでしょうか。

    • ベストアンサー
    • Perl
  • データからある文字列の次の行を出力するには

    perlの初心者です。はじめまして。 質問タイトルそのままなのですが、データからある文字列の次の行を出力するにはどのような記述をすればよろしいでしょうか?よろしくお願いします。 ・データは1ファイルで2000あります。1つのデータは[X,Y]で始まり、次の[X,Y]の前までになります。 ・出力はCSVファイル。 ・DAT errがあった場合はその次の行を出力。なかったら、DAT列は空白にする。 #!/bin/perl open(FILE,"<$ARGV[0]"); open(OUT,">$ARGV[0].csv"); ########################## err count ########################### print OUT "X,Y,NUMBER,DAT,\n"; while(<LOG>){ if($_ =~ /X=(.+)\,Y=(.+)/){ chomp($_); print OUT "\n$1,$2,"; } if($_ =~ /NUMBER (.+)/){ print OUT "$1,"; } if($_ =~ /DAT err/){ print OUT "PASS,0,"; } } close(OUT);

    • ベストアンサー
    • Perl
  • Perl初心者です。同一データを数えるには

    perl 超!初心者です。同一データの数え上げ。 あまり上手く説明できませんがよろしくお願いします。 ある行から行までの同一データを数え上げる処理をしたいです。 例えば、以下のようなデータがあるとします。 --------------------- <NAME> 田中 佐藤 佐藤 山田 田中 <NAME> 佐藤 田中 渡辺 渡辺 佐藤 ------------------- while (<>){ $linecount{$_}++; } foreach $line (sort{$linecount{$b} <=> $linecount{$a}}keys%linecount) { print $linecount{$line}," ",$line if($linecount{$line} >= 1); } これで、行の重複回数と、データを出力はできたのですが、 さらに、<NAME>で区切ってそれぞれの区分で同一データの数を数えていきたいです。結果としては <NAME> 2 田中 2 佐藤 1 山田 <NAME> 2 渡辺 2 佐藤 1 田中 と出力したいのですが、どうすればよいでしょうか?

    • ベストアンサー
    • Perl
  • Perlで2つのテキストファイルの処理する方法

    めぐみです。 tatsu99さま、以下のプログラムを親切にアドバイス頂きまして本当にありがとうございました。 追記で質問させて頂きたいことがあります。 --------------------------------------------------------------- $file_a = shift(@ARGV); $file_b = shift(@ARGV); open FHA,$file_a or die("can't open $file_a"); @data_a = (); while($line=<FHA>){ chomp($line); push @data_a,$line } close FHA; open FHB,$file_b or die("can't open $file_b"); @data_b = (); while($line=<FHB>){ chomp($line); push @data_b,$line } close FHB; foreach $da (@data_a){ printf("%s%d%d%d\n",$da,$data_b[0],$data_b[1],$data_b[2]); printf("%s%d\n",$da,$data_b[0]); printf("%s%d%d\n",$da,$data_b[1],$data_b[2]); printf("%s\n",$da); printf("%s%04d%02d%02d\n",$da,$data_b[0],$data_b[1],$data_b[2]); printf("%s%02d%02d\n", $da,$data_b[1],$data_b[2]); printf("%d%d%d%s\n",$data_b[0],$data_b[1],$data_b[2],$da); printf("%d%s\n",$data_b[0],$da); printf("%d%d%s\n",$data_b[1],$data_b[2],$da); printf("%s\n",$da); printf("%04d%02d%02d%s\n",$data_b[0],$data_b[1],$data_b[2],$da); printf("%02d%02d%s\n",$data_b[1],$data_b[2],$da); }--------------------------------------------------------- 下記のような内容を追加で出力させることは難しいでしょうか。 1.B.txtを元に下記のように数字だけのデータも追加で出力させたかったです(1行目1986,2行目3,3行目6の場合) 198636 1986 36 19860306 0306 2.A.txtを元にA.txtから下記の内容も追加で出力させたかったです(4行目以降は無視して構いません)。 1行目と2行目 2行目と3行目 3行目と1行目 2行目と1行目 1行目と3行目 3行目と2行目 以上、何卒よろしくお願いいたします。

  • おかしなif文だと思うのですが、どう思われますか?

    $a=10; $b=20; if($a>=$b){ print "\$aは\$bと等しいかおおきいですよ。\n"; } elsif($a>$b){ print "\$aは\$bより大きいです。\n"; } elsif($a<$b){ print "\$aは\$bより小さいです。\n"; } ある例題のif文なんですが、 $a>=$bで$a>$bは内包されているはずなので elsifの例として不適切ですよね。 どう思われますか?

    • ベストアンサー
    • CGI