• ベストアンサー

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

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

  • Perl
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • 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

  • 同じ番号のデータを別のファイルにはきだだすには?

    下の画像のようのデータを一行一行みていき、先頭二桁が上の行と同じ場合それを同じファイルに一行一行はきだしたいです。 例 3,4,5行目は3.txt ファイルにはきだす。6.7行目は2.txtファイルにはきだす。その他は1.txtファイルにはきだす。 シンプルでわかりやすい方法を教えていただきたいです。 よろしくお願いいたします。

  • Excel 複数の項目合致するデータを抽出したい

    是非、よろしくお願いいたします。 以下の状況です。 sheet1には A、B、C、Dという4列があります。データは1000行くらいです。 sheet2には A、B、C、Eという4列があります。データは2000行くらいです。 この状況で、sheet1のD列の右に新しい列を作り、 「sheet1の(例えば)A1、B1、C1と合致する行のsheet2のE列データ」を、 sheet2のABC列範囲を検索して抽出したいのです。 項目が一つであればvlookup関数でできるものを「複数項目に合致」のため上手くいきません。 この3列のデータを結合して一つにしてみましたが、結合後のデータが16桁以上のため末尾が「0」になってしまい、正確に検索できません。 何か上記を可能にする方法はないでしょうか? よろしくお願いいたします。

  • EXCEL セル内の数値から、5桁目だけを抽出する方法について

    EXCELシートのセル内に、以下のような30桁からなる数値が入力されている 列が複数あります。 この列内の数値の右端から「5桁目」だけ、または左端から「10桁目」だけを 抽出したいと思っているのですが、EXCELの仕様で数値の先頭にある「0」は 表示されないため、各セルごとに表示されている数値の桁数はバラバラです。 数値の先頭に「0」が付いているセルが多数あり桁数が不揃いなことと、 数値が30桁もあるため、セルの数値表示が「1E+29」のように「E+29」で表示 されてしまっており、うまく数値を抽出することが出来ません。 ◆元データ   「列1」     (1) 1234567890  →(本当は30桁:000000000000000000001234567890)    (2) 111111111100000000001111111111   (3) 1      →(本当は30桁:000000000000000000000000000001)  (4) 123456789012345678909999999999  ◆右端から5桁目だけを抽出する   「列1」      (1)  6      (2)  1      (3)  0      (4)  9   お手数お掛けいたしますが、ご指導下さいますよう宜しくお願い致します。

  • 大量データから抽出する際の効率よいperlプログラム作成について教えて

    大量データから抽出する際の効率よいperlプログラム作成について教えてください。 例) 大量データ Aファイル 3列 可変値(数値、URL、数値)タブ区切り 重複値あり 123 http://www.XX.co.jp/XX 4567 1111 http://www.XX.co.jp/XX 3333 3 http://www.XX.co.jp/YZ 4567 1111 http://www.YYY… 116 … 抽出対象データ Bファイル 1列(URL)重複なし http://www.XX.co.jp/XX http://www.XX.co.jp/ZZZ … Aファイル、BファイルともにURL降順ソートされている BファイルにあるURLがAファイルにある場合 Aファイルのその行を抽出したい。 grepで実施すると すごい時間がかかってしまうため、効率よい抽出方法をおしえてください。

    • ベストアンサー
    • Perl
  • vbaで特定の番号から番号の表データを抽出

    任意の範囲で表からデータを抽出することができるのでしょうか? 行は100行で列は7列、1行めは項目行で、1列目の2行目から1番から99番までが割り当てられています。1行目の2列目から7列目まで項目が割り当てられています。その他のセルには数値や文字データが入力されています。 こんな表から、任意に、例えば10行目から35行目までのセルデータ全てを別シートに取り出すそんな抽出方法があるのでしょうか?皆目検討がつきません。もし可能ならどなたかお教え頂けませんか?

  • 文字列抽出についてご質問です。

    文字列抽出についてご質問です。 csvファイルの中に、http://hoge.com/◎◎/goods_parts/◎◎/数字1~5桁/◎◎・・・ のようなデータがずらっと1000行くらいあって、 このURLの中にある数字1~5桁が、別ファイルの1~5桁の数字だけがあるファイルと合致したら、 出力のようにしたいです。 そこで、phpかexcelvbの正規表現で、 ・数字のみを抽出するサンプルコードをおしえていただけないでしょうか。 なにとぞよろしくお願いいたします。

    • ベストアンサー
    • PHP
  • VBSにてDNSサーバなどアドレス抽出

    すいませんが、以下の方法がわかりませんでしたのでご教示ください。 それぞれのテキストファイルにはPCのDNSやWINSサーバのアドレスを記述しています。 テキストファイルを一行ずつ読み込まして、テキスト内に記述しているDNSやWINSサーバのデータを抽出しようとしています。 DNSやWINSのブライマリは一行なので、抽出条件(IF文)で該当した行を出力させていますが、 セカンダリは存在しない場合、一行存在する場合、複数行存在する場合とまちまちで困っております。 例えば、一行ずつ読み込ましているデータの中に、「DNSセカンダリ」という文字があれば、instr関数を使用してその行を取得しています。 ただ複数DNSセカンダリを設定している場合は、次の行も取得しなければいけません。 次の行には「DNSセカンダリ」という文字がないので、抽出対象とできませんが、どうすれば複数行あったときでも抽出させることができるでしょうか。

  • 数値の抽出

    添付の表の注文番号には、管理番号が含まれています。表のように、その管理番号を抽出する関数式をご教授下さい。 抽出条件としては、 (1)注文番号の中には、部門を示す4桁の数値(複数)があります。この4桁の数値のすぐ左にある"-"と"-"の間の英・数値を取り出す。 (2)"-"で囲まれていない場合は、左先頭から"-"迄の英・数値を取り出す。 (3)4桁の数値が含まれていない場合は、左先頭から"-"までの英・数値("-"が無い場合は、全ての英・数値)を取り出す。 以上宜しくお願いします。

  • perlで先頭の数値をみて昇順にならびかえたい。

    perlで先頭の数値をみて昇順にならびかえたい。 以下のようなデータの先頭の二桁の数値をみて、昇順に行ごと並び替えをしたいです。 sort を使えば簡単にできるのでしょうか? perlをはじめたばかりでよくわかりません。 ぜひ詳しく教えてください。お願いします

  • 大量データから抽出する効率よいperlプログラムは

    以前も質問させていただきましたが、 大量データから抽出する際の効率よいperlプログラム作成について また、教えてください。 例) 大量データ Aファイル 3列 可変値(数値、URL、数値)タブ区切り 重複値あり 123 http://www.XX.co.jp/XX 4567 1111 http://www.XX.co.jp/XX 3333 3 http://www.XX.co.jp/YZ 4567 1111 http://www.YYY… 116 … 抽出対象データ Bファイル 1列(URL)重複なし http://www.XX.co.jp/X http://www.YYY.co.jp … BファイルにあるURLで始まるURLがAファイルにある場合 Aファイルのその行を抽出したい。 grepで実施すると すごい時間がかかってしまうため、効率よい抽出方法をおしえてください。 今回は、完全一致ではなく、Bファイルに入っているリストのURLから始まるものにしたいと考えているので、前の手法(hash連想配列)が使えないと考えております。 Aファイルが容量大きいため、grep処理では1週間たっても終わらないのです。

    • ベストアンサー
    • Perl

専門家に質問してみよう