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

お世話になります。
perl初心者です。2つのファイル、A.txtおよびB.txtがあり
各ファイル2列でタブ区切りになっている
ものとします。
一列目をキーにして、マージし、merge.txtを作成したいと考えております。
ハッシュで行うとDの要素が上書きされて一つになってしまいます。

大変申し訳ございませんが、改善策をお教えいただけないでしょうか。
どうぞよろしくお願い致します。

A.txt
A 1
B 2
C 3
D 4
D 5
D 6

B.txt
A X
B Y
C Z
D W

merge.txt
A 1 X
B 2 Y
C 3 Z
D 4 W
D 5 W
D 6 W

open(IN,"A.txt");
while($line=<IN>) {
chomp($line);
my@dataA=split(/\t/,$line);
$hashA{$dataA[0]}=[@dataA]
;}
close(IN);

open(IN2,"B.txt");
while($line2=<IN2>) {
chomp($line2);
my@dataB=split(/\t/,$line2);
$hashB{$dataB[0]}=[@dataB]
;}
close(IN2);

open(OUT,">merge.txt");
foreach $key (sort keys %hashA) {
print OUT join("\t",$key,@{$hashA{$key}}[1],@{$hashB{$key}}[1]),"\n";
}
close(OUT)

A 回答 (3件)

>ご質問1


>next処理でお願いします。
X 1 2 3
と理解しました。
以下のようにしてください。
%hashAの要素は、@linesの要素番号を配列で格納してます。
@linesはA.txtの各行を格納しています。(B.txtの新規のキーの行も格納しています)
B.txtのキーがA.txtにあれば、B.txtの該当要素を@linesの該当位置に付け加えます。
---------------------------------------
open(IN,"A.txt");
my @lines = ();
my $ix = 0;
while($line=<IN>) {
chomp($line);
push(@lines,$line);
my @dataA=split(/\t/,$line);
if (exists $hashA{$dataA[0]}){
$ref = $hashA{$dataA[0]};
push(@$ref,$ix);
}else{
$hashA{$dataA[0]}=[$ix];
}
$ix++;
}
close(IN);

open(IN2,"B.txt");
while($line2=<IN2>) {
chomp($line2);
my @dataB=split(/\t/,$line2);
if (exists $hashA{$dataB[0]}){
$ref = $hashA{$dataB[0]};
foreach $wx (@$ref){
$lines[$wx] .= "\t" . $dataB[1];
}
}else{
push(@lines,$line2);
$hashA{$dataB[0]}=[$ix];
$ix++;
}
;}
close(IN2);

open(OUT,">merge.txt");
foreach $line (@lines) {
print OUT $line,"\n";
}
close(OUT)
------------------------------------
    • good
    • 0
この回答へのお礼

tastu99様

ご連絡ありがとうございました。
動作の確認ができ大変助かりました。
スクリプトを理解して、応用したいと思います。

どうもありがとうございました。

お礼日時:2017/04/28 08:37

補足要求です。


1)B.txtの中に1列目の値がA.txtにない場合、どのようになりますか。
提示されたB.txtに
X 1
X 2
X 3
がある場合、
merge.txtは
X 1
X 2
X 3
ですか?
X 1 2 3
ですか?
2)B.txtの中に1列目と2列目が同じものがあった場合でもそのまま処理して良いですか。
例として
B.txtに
A X
A X
B Y
B Y
C Z
C Z
D W
D W
のようにあった場合、
merge.txtは
A 1 X X
B 2 Y Y
C 3 Z Z
D 4 W  W
D 5 W W
D 6 W W
のようになりますが良いですか。
    • good
    • 0
この回答へのお礼

ご連絡ありがとうございました。
ご質問1
next処理でお願いします。
ご質問2
条件の説明が不足しており申し訳ございませんでした。
B.txtは、重複がないファイルとして考えております。

どうぞよろしくお願い致します。

お礼日時:2017/04/27 20:33

いきなりプログラム記述言語(この場合Perl)で考えていませんか?


処理アルゴリズムは普段日常で使用している自然言語(例えば日本語)で考えましょう。
ただし、実装言語が持つツール機能を使う場合はその機能を前提に考えてもかまいません。

質問に書かれている問題の場合、両ファイルのレコードが書かれている順であることを前提とするのか(=それ以外外の場合は誤動作したり異常終了したりしてもかまわない)、書かれている値を前提とするのか、などで求めるアルゴリズムの完成度が変わるかと思います。
例えば前者はA、B、Cの順に並んでいないという場合にも対応するかどうかです。
例えば後者はA.txtが以下などの場合でもちゃんと動くようにするのかです。

A 1
B 2
C 3
C 4
C 5
D 6

そういったことを決めた上で、それはどういう処理をどういう順序でどのように繰り返したら求める結果(merge.txt)が得られるかを日常使用している自然言語で考えるわけです。
考えた内容は箇条書きや、ご存じなのでしたらフローチャートなどのチャート図に表して行くと考えやすいですし、間違いが無いかの見直しもしやすいです。

参考まで。
    • good
    • 1
この回答へのお礼

ご助言をありがとうございました。
なかなか自然言語として考えることが
できずにおります。

お礼日時:2017/04/27 20:28

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