
お世話になります。
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)

No.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)
------------------------------------
tastu99様
ご連絡ありがとうございました。
動作の確認ができ大変助かりました。
スクリプトを理解して、応用したいと思います。
どうもありがとうございました。

No.2
- 回答日時:
補足要求です。
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
のようになりますが良いですか。
ご連絡ありがとうございました。
ご質問1
next処理でお願いします。
ご質問2
条件の説明が不足しており申し訳ございませんでした。
B.txtは、重複がないファイルとして考えております。
どうぞよろしくお願い致します。
No.1
- 回答日時:
いきなりプログラム記述言語(この場合Perl)で考えていませんか?
処理アルゴリズムは普段日常で使用している自然言語(例えば日本語)で考えましょう。
ただし、実装言語が持つツール機能を使う場合はその機能を前提に考えてもかまいません。
質問に書かれている問題の場合、両ファイルのレコードが書かれている順であることを前提とするのか(=それ以外外の場合は誤動作したり異常終了したりしてもかまわない)、書かれている値を前提とするのか、などで求めるアルゴリズムの完成度が変わるかと思います。
例えば前者はA、B、Cの順に並んでいないという場合にも対応するかどうかです。
例えば後者はA.txtが以下などの場合でもちゃんと動くようにするのかです。
A 1
B 2
C 3
C 4
C 5
D 6
そういったことを決めた上で、それはどういう処理をどういう順序でどのように繰り返したら求める結果(merge.txt)が得られるかを日常使用している自然言語で考えるわけです。
考えた内容は箇条書きや、ご存じなのでしたらフローチャートなどのチャート図に表して行くと考えやすいですし、間違いが無いかの見直しもしやすいです。
参考まで。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CSSのhtmlへの紐付けについ...
-
100万件越えCSVから条件を満た...
-
一週間用のカレンダー
-
Ruby require ライブラリー
-
ruby OpenURI::Meta
-
ruby while式
-
ruby loopメソッド 変数(再喝)
-
ruby 配列
-
ruby loopメソッド 変数
-
ruby クラス・オブジェクト・イ...
-
ルビー言語 ライブラリー 追記
-
ruby raise句
-
ruby begin句
-
ruby ensure句
-
ルビー言語 ライブラリー(再々...
-
ルビー言語 csvファイル 続き(...
-
ルビー言語 csvファイル 続き
-
ルビー言語 ライブラリー
-
ルビー言語 csvファイル part2
-
ルビー言語 ライブラリー
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッチ処理 特定の文字以降を...
-
Access VBA エラー2448について
-
VBA テキストボックスを選択状...
-
[コンパイルエラー 修飾子が不...
-
パイソンでのファイルを見るには
-
Excel VBAでループ?続けて処理...
-
VBAで繰り返し持ってきた文章の...
-
verilog HDLについての質問です...
-
フォームのResizeイベントについて
-
teratermで、ファイル名をinput...
-
型の値をDataGridViewセルに変換...
-
MS-DOSバッチファイルコマンド...
-
SQLでテキストボックスの文字を...
-
超初心者です。シングルクォー...
-
パイソンでテキストファイルが...
-
バッチファイル フォルダ名をフ...
-
分数の計算のプログラミングです。
-
テキストboxに数値を入れる...
-
Dreamweaverでtitleタグ内の一...
-
ruby テキストファイル書き出し...
おすすめ情報