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

perl初心者です。複数のファイルの処理について悩んでいます。

text-a
ab
ac
bc

text-b
a,1
b,2
c,3

とのような二つのテキストファイルで、
text-aの文字の中に、text-bの左の文字が含まれているとき
text-bの該当する文字の右側の数字を足して、text-aの右側に加えて書きだしたいです。

この例だと
ab 3
ac 4
bc 5
という風にしたいです。

open closeなどは省いています。text-aは実際は他にも情報があって、その分プログラムが多くなっていますが、$a1 = text-a の文字の部分になるようにしています。

while($str = <FILE_IN1>){
chomp($str);
@tmp = split(/\t/, $str);
@tmp1 = split(/,/, $tmp[0]);
@tmp2 = split(/,/, $tmp[1]);
$a1 = $tmp1[0];  

while($str0 = <FILE_IN2>){
chomp($str0);
@tmp0 = split(/,/ , $str0);
@b1 = @tmp0[1];
@b2 = @tmp0[2];

if($a1 =~ /$b1/){$a2 += $b2;}}

print FILE_OUT1 "$a2,$a2\n";
}

というプログラムを書いたのですが、数字を足して書き出す部分が上手くいかず、何故よくないのかさえわからない状態です...。
ご教示お願いします。

質問者からの補足コメント

  • ご指摘ありがとうございます。
    $b1 = $tmp0[1];
    $b2 = $tmp0[2];
    の書き間違いです。
    直すと、数字部分が全て1で表示されます。
    よろしければまた教えてください。

    No.1の回答に寄せられた補足コメントです。 補足日時:2017/11/13 08:34
  • 何度も小さなミスをすみません...。本当にありがとうございます。
    $b1 = $tmp0[0];
    $b2 = $tmp0[1];
    "$a1,$a2\n"
    で修正しました。
    open,closeは他のプログラムだと動いていたので問題ありません。

    $a2のクリアは、二つ目のwhileの前に
    $a2 = 0;
    かなと思ってやってみたのですが、
    次は$a2の表示が一番初めは1、
    後は全て0の表示になってしまいました...。

    No.2の回答に寄せられた補足コメントです。 補足日時:2017/11/13 14:45

A 回答 (4件)

うん, そうなってるだろうなと思った.



内側の while ループの動きを考えてみよう. まず, text-a.txt の 1行目のデータに対して FILE_IN2 から全データを読み込むよね. その次, text-a.txt の 2行目のデータに対して FILE_IN2 からデータを読み込もうとするんだけど, FILE_IN2 からはもう全てのデータを読み込んじゃってるのでそれ以上読み込めないんだよ.

3行目以降も全部同じことなので「後は全て0の表示になってしまいました...。」という結果になる, と.
    • good
    • 0
この回答へのお礼

一度全て読み込むと、次に読み込むときは
またファイルを開かないといけないんですね;
whileの中にopenを入れてopenも繰り返すようにしないといけなかったのですね。
無事に正しい結果を出すことができました。
知識が浅い私に、根気強く丁寧に教えてくださり、ありがとうございました。
とても勉強になりました。
本当にありがとうございました。

お礼日時:2017/11/14 16:32

本当にちゃんとできてるんだろうか....



open や close を含めたプログラムを見せてもらえませんか?
    • good
    • 0
この回答へのお礼

何度も、すみません。よろしくおねがいします。

use utf8;
use Encode qw/encode decode/;

open(FILE_IN1, "<:utf8", "text-a.txt") or die "Can't open file!";
open(FILE_IN2, "<:utf8", "text-b.txt") or die "Can't open file!";
open(FILE_OUT1, ">text-c.txt");

while($str = <FILE_IN1>){
chomp($str);
@tmp = split(/\t/, $str);
@tmp1 = split(/,/, $tmp[0]);
@tmp2 = split(/,/, $tmp[1]);
$a1 = $tmp1[0];  

while($str0 = <FILE_IN2>){
chomp($str0);
@tmp0 = split(/,/ , $str0);
$b1 = $tmp0[0];
$b2 = $tmp0[1];

if($a1 =~ /$b1/){$a2 += $b2;}}
$a1 = encode('UTF-8',$a1);
$a2 = encode('UTF-8',$a2);
print FILE_OUT1 "$a1,$a2\n";
}
close(FILE_IN1);
close(FILE_IN2);
close(FILE_OUT1);

お礼日時:2017/11/13 18:31

あ,


$b1 = $tmp0[1];
$b2 = $tmp0[2];
の添え字がたぶんおかしい.

あとは
・$a2 のクリアが書かれていない
・最後に表示するのは "$a2,$a2\n" でいい?
・ファイルの open, close はちゃんとできてるよね?
くらいかな.
この回答への補足あり
    • good
    • 0

@b1 = @tmp0[1];


とか
@b2 = @tmp0[2];
とかって, どうして配列を使ってるんですか?
この回答への補足あり
    • good
    • 0

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