2016-08-19 9 views
1

大きなファイルに1M行以上の文字列があり、大きなファイルに一致する行を取得するのに必要な入力文字列を持つファイルがあります。 。ループ内の大きなファイルを別のファイルの入力として処理する方法

私はそれをこのように行うことができました:

File.open(strings_file, 'r') do |l| 
    File.open(large_file, 'r') do |line| 
    next if !line.include?(l) 
    puts line 
    end 
end 

をしかし、それは各ループの大きなファイルを開きます。たとえば、input-stringには100行の文字列があるので、実行するとその大きなファイルを100回開いて処理するので、完了に時間がかかります。

大きなファイルを100回開くのを避ける方法がありますか?

答えて

5

まず、あなたがこれを間違えた場合、幾何学的スケーリングの問題が発生します。入力ファイルAにN行、B行にM行がある場合、オーバーラップをチェックするにはN * Mテストを行う必要があります。それは非常に遅くなる可能性があります。代わりに

、入力ラインに引くとクイック検索に使用できるものでそれらを固執:

require 'set' 
match_lines = Set.new(File.readlines(strings_file).map(&:chomp)) 

次に、あなたはここで非常に迅速にテストすることができます。

File.foreach(large_file) do |line| 
    print line if (match_lines.include?(line.chomp)) 
end 

を私はchompを使用していますマッチファイルの最後の行に最後に改行がない場合、または一方でCRLFエンコーディングを使用し、もう一方でLFを使用している場合は、マッチしないようにします。

+0

ニース!しかし、match_linesのせいで動作しないのは単なる文字列であり、line変数の値には特殊文字と文字列の両方が含まれます。逆の方法で '(match_lines.include?(line.chomp))'を実行する必要があると思います。逆の方法でそれを行う方法がわからない。 – Karthi1234

+0

"逆の道"についてどういう意味ですか? 'strings_file'にはどんなコンテンツがありますか? – tadman

+1

strings_file内容: '試験 ワード アンバー 赤色 blue' 上記文字列と一致する Larger_file内容: ' 'テスト、これはT3Eする$ Tファイル' と '位置/ MNT' 。 。 青、色は青、 'RGBの一部です' 希望が明確になりました – Karthi1234

関連する問題