質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

Q&A

解決済

1回答

1109閲覧

perlで①のファイルの複数キーワードと合致するキーワードを②のファイルで探し、②からキーワードと紐づく情報を抽出したい

kusagi

総合スコア11

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

0グッド

0クリップ

投稿2018/08/30 15:23

前提・実現したいこと

sample.txtは全製品の仕様です。英数字の羅列は今回の質問用に仮作成
しております。今回、4つの製品が製品Noで発注されたため(keylist.txt)、
お客様にkeylistの製品Noの横にsample.txtから工場以降の情報を
抜き出して製品Noの横に付けたいです。実現したい形は下部に載せます。
実際にはsample.txtが50万行、keylist.txtが8000行もあり、while文
だけで回すと膨大な時間になるので諦め、ハッシュを使うべくTryしています。

(sample.txt)
製品No     工場 製品型番 年式  材料No  備考
AAAXAB02018 AAA XAB0 2018 500A AAA-FFHB-AAS
BBBXXX82017 BBB XXX8 2017 600B AAA-FFHB-AAS
ABAXAB02018 ABA XAB0 2018 322A AAA-FFHB-AAS
CDEPPL32015 CDE PPL3 2015 500A AAA-FFHB-AAS
ZZZACDF2016 ZZZ ACDF 2016 600B AAA-FFHB-AAS
YDCXAB02018 YDC XAB0 2018 322A AAA-FFHB-AAS
POKXAB02017 POK XAB0 2017 500A AAA-FFHB-AAS
HGVYYO12018 HGV YYO1 2018 600B AAA-FFHB-AAS
DDFXAB02015 DDF XAB0 2015 322A AAA-FFHB-AAS
RRMXXX82016 RRM XXX8 2016 500A AAA-FFHB-AAS
EDMXAB02018 EDM XAB0 2018 600B AAA-FFHB-AAS
AENPPL32017 AEN PPL3 2017 322A AAA-FFHB-AAS
UNMACDF2018 UNM ACDF 2018 500A AAA-FFHB-AAS
DKNXAB02015 DKN XAB0 2015 600B AAA-FFHB-AAS
RGBXAB02016 RGB XAB0 2016 322A AAA-FFHB-AAS
SMKYYO12018 SMK YYO1 2018 500A AAA-FFHB-AAS
UFFXAB02017 UFF XAB0 2017 600B AAA-FFHB-AAS
HKEXXX82018 HKE XXX8 2018 322A AAA-FFHB-AAS
WDGXAB02015 WDG XAB0 2015 500A AAA-FFHB-AAS
MMMPPL32016 MMM PPL3 2016 600B AAA-FFHB-AAS
BKFACDF2018 BKF ACDF 2018 500A AAA-FFHB-AAS
LIKXAB02017 LIK XAB0 2017 600B AAA-FFHB-AAS
JDTXAB02018 JDT XAB0 2018 322A AAA-FFHB-AAS

(keylist.txt)
製品No
ZZZACDF2016
DDFXAB02015
UNMACDF2018
RGBXAB02016

(最終的に実現したい形)
keylist.txtの製品番号と一致する情報をsample.txtから検索し
製品番号以降の情報を右側に付けて出力したい。

ZZZACDF2016 ZZZ ACDF 2016 600B AAA-FFHB-AAS
DDFXAB02015 DKN XAB0 2015 600B AAA-FFHB-AAS
UNMACDF2018 UNM ACDF 2018 500A AAA-FFHB-AAS
RGBXAB02016 RGB XAB0 2016 322A AAA-FFHB-AAS

発生している問題・エラーメッセージ

最終的な出力ファイルresule.txtのファイルに何も出力されません。
perlは今回の新たな仕事用に初めて学び、今現在学びながらプログラムを
書いているため、もしかしたらエラーを出すべき適切な設定ができていない
と思います。未熟なコードとなり申し訳ございません。

該当のソースコード

#!/usr/bin/perl

my %product_datas = ();
open(IN,"sample.txt");
while(<IN>){
chomp;

if(/^(\w+)\t(.+)/){
$keyword = $1;
$item = $2;

%product_datas = ($keyword=>$item);
}
}
close(IN);

open(OUT, '>result.txt');
open(KEY, 'keylist.txt');

while(<KEY>){
chomp;
$line = $_;

if( exists $product_datas{$line}){ print(OUT "$line\t$product_datas{$line}\n"); }

}
close(KEY);
close(OUT);

試したこと

まずそもそもハッシュ%product_datasにデータがきちんと格納されて
いるか確認するため、 %product_datas = ($keyword=>$item);の
下に
foreach my $key (keys(%product_datas)){
print "$product_datas{$key}\n";
}
を記述し出力させたところ、sample.txtの製品Noより後ろの部分は
抜き出せていました。しかし最終的な出力
print(OUT "$line\t$product_datas{$line}\n");
では最初にファイル出力でなく画面出力で確認しましたが、何も出力
されませんでした。どう進めるべきか分からず悩んでおります。

補足情報(FW/ツールのバージョンなど)

PCはwindows7 professionalです
perlのverはv5.26.2です。
環境はGit for windowsをインストールし、その中のパッケージ
されているperlを使っています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KojiDoi

2018/08/30 18:02

質問文の中にコードを含めるときは、その前後を```で挟んでください。 https://teratail.com/questions/123033 この質問の中で、LouiS0616さんが図で分かりやすく説明されているので参考にしてください。 これにより、コード部分が視覚的に区別しやすくなり、インデントも再現され、なにより、回答者が自分の環境でコードを実行しようとするときにコピペが大変簡単になります。
kusagi

2018/08/31 12:45

ご教授頂きありがとうございます。もし次回質問させて頂く際は、注意致します。
guest

回答1

0

ベストアンサー

まず少なくとも一つ致命的な問題があります。

%product_datas = ($keyword=>$item);

これでは実行するたびに前の定義を全部消して新しくハッシュを作り直すことになるため、最後の行のデータしか残りません。

正しくは、こうでしょう。

$product_datas{$keyword} = $item;

この例では、アルゴリズムにも改善の余地がありそうです。まず%keylistの読み込みを先にしたほうがいいでしょう。それで商品番号をhashにため込んでおきます。次にsample.txtをオープンして、hashに番号の合致するものがある場合のみ処理を実行するようにすれば、sample.txtが何百万行あろうとメモリが足りなくなったりはしないでしょう。

投稿2018/08/30 18:27

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kusagi

2018/08/31 12:49

アドバイスありがとうございました。hashハの基本的な考え方、使い方が分かっておらずご迷惑をおかけいたしました。頂いたアドバイス通りに'%keylist'の読み込みを先にし、それを最初にhashに入れるようにしてみました。その後sample.txt(本番は52万行)を読み込んで実行したところ、わずか数分足らずで処理が完了しperlの処理能力の高さに改めてビックリしてしまいました。今後とも勉強を続けます、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問