• ベストアンサー

合致する番号のデータを抽出する方法を教えてください

合致する番号のデータを抽出する方法をおしえてください perlの勉強を始めたばかりの初心者です。 下の画像のようにタブで区切られたデータです。一行で一人分のデータです。 先頭の4桁の数値がユニークで、この数値をつかって抜き出します。 0125 0251 2650 : : : 上記のように与えられた別ファイルの数値と合致する行だけを抜き出し別ファイルにはきだす方法を教えていただきたいです。 シンプルでわかりやすいもの、メモリに負担のすくないものなど複数の方法を教えていただきたいです。 説明もいただけるとありがたいです。よろしくお願いします。

質問者が選んだベストアンサー

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

1. ハッシュを使う 2. 「別ファイルの数値」を覚えておいて 1行ずつチェック

kosiba
質問者

補足

恐れ入りますが、具体的にハッシュを使い、 1行ずつチェックするとはどののように書けばよいのか教えていただけませんでしょうか?

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

「プログラムは簡単だ」とは言いませんが、難しく考えすぎないことがコツだと思います。 まず、「方法」自体は、Perlの技術とは直接関係ありません。 手作業でやるときの「方法」を分析して、コンピュータにやらせる、というのがお手軽なやり方です。 Perlは、その「コンピュータにやりかたを教える」ために使います。 手作業でやる場合、例えば、こんな風にやります。 ファイル1の1行目を見る→ファイル2の中にあるか調べる→あったら出力 ファイル1の2行目を見る→ファイル2の中にあるか調べる→あったら出力 .... ファイル1の最終行を見る→ファイル2の中にあるか調べる→あったら出力 これを、コンピュータに教えるために、Perl で記述します。 1行目から最終行まで順番、となると、定番の while(<>){~}です。 open $fp1,'<','ファイル1'; while( $line1 = <$fp1> ) { open $fp2,'<','ファイル2'; while( $line2 = <$fp2> ) { if( $line1と$line2とを番号で比較して合致する ) { print 該当行のデータ } } close $fp2; } close $fp1; (一部の記述を具体的書けば)これで完成です。 1,2回使うだけなら、これで十分。「効率のいいプログラム」を作っている間に処理が終わります。 今後、何度も使う。あるいは、技術を身に付けたい、という場合は、効率化を考えていきます。 例えば。ファイルを毎回読み直すのは非効率的です。(メモリに余裕があるなら)全部読み込んでしまいます。 open $fp2,'<','ファイル2'; @lines1=<$fp2>; # 全部の行をリストに読み込む close $fp2; open $fp1,'<','ファイル1'; while( $line1 = <$fp1> ) { foreach $line2 (@lines2) { if( $line1と$line2とを番号で比較して合致する ) { print 該当行のデータ } } } close $fp1; # ファイル2を数値ファイルにすると、#1にある「2. 「別ファイルの数値」を覚えておいて 1行ずつチェック」になります。 (Perlでの)ハッシュは、キー文字列と値をセットで扱うデータ構造です。 例えば $data{'0024'}='0024 佐藤一郎 東京都' ; としてあれば print $data{'0024'} ; で 「0024 佐藤一郎 東京都」と出力されます。 これを使って データファイルを読み込みハッシュを作る→数値ファイルから一行読んで、ハッシュにあったら出力 とすれば、一つずつ比較する必要がありません。 #ハッシュテーブルを作る open $fp2,'<','データファイル'; while($line2=<$fp2> $data{数字部} = $lines2; close $fp2; # 数値ファイルから読み込む open $fp1,'<','数値ファイル'; while( $line1 = <$fp1> ) { # <>では改行文字まで込みで読みこまれるので、取り除く # ※初心者が嵌りやすい罠です chomp($line1) # キーが存在しなければundefになる # この場合、undefは空文字列扱いされるので、なにも出力されない print $data{$ine1}; } close $fp1;

すると、全ての回答が全文表示されます。

関連するQ&A