2017-05-11 14 views
0

ファイル(d:\ mywork \ list.txt)を1行ずつ読み込み、その文字列が特定のファイル(1つずつ)ディレクトリ(d:\ new_work)。複数のファイルから行を削除する方法

いずれかのファイル(存在する可能性があります)に存在する場合は、それぞれのファイルから文字列(car \ yrui3、)を削除してそれぞれのファイルを保存します。

list.txtに:D:\のnew_work:

Rollcar-access.txt 
Mycar-access.txt 
Newcar-access.txt 
....... 
...... 

マイコード:

value=File.open('D:\\mywork\\list.txt').read 
value.gsub!(/\r\n?/, "\n") 
value.each_line do |line| 
    line.chomp! 
    print "For the string: #{line}" 
    Dir.glob("D:/new_work/*-access.txt") do |fn| 
     print "checking files:#{fn}\n" 
     text = File.read(fn) 
     replace = text.gsub(line.strip, "") 
     File.open(fn, "w") { |file| file.puts replace } 
    end 
end 

問題は値が取得されていません、ある複数のファイルを持つ

car\yrui3, 
dom\09iuo, 
id\byt65_d, 
rfc\some_one, 
desk\aa_tyt_99, 
......... 
......... 

ディレクトリ期待どおりに削除されました。また、値を印刷しようとしたときにtextが空です。

+1

私たちはあなたが新人であるか経験者であるかには関心がありません。よく調査され、よく尋ねられ、簡潔な質問が必要です。私はSOなどのコミュニティでの作業について説明しているので、「[スマートウェイの質問方法](http://catb.org/esr/faqs/smart-questions.html)」を読むことをお勧めします。 –

+0

あなたの仕事は多少なりとも "[XY問題](https://meta.stackexchange.com/q/66377/153968)"です。あなたはおそらく最初にタスクを解決することについて質問していたはずですが、実装について質問しています。問題を再考することをお勧めします。ファイルは何を表していますか?なぜデータは複数のファイルに分散していますか?データベースを使用してファイルの内容を保存することを検討してください。迅速に検索および削除することができます。 SQLiteでもこれを素早く処理でき、Sequel、Datamapper、Active RecordなどのORMを使用すると非常に簡単に処理できます。 –

答えて

2

コードにはいくつかの問題があり、ファイルの変更を安全に処理していません。

この未テストコードの瞑想:あなたが使用してコードで

ACCESS_FILES = Dir.glob("D:/new_work/*-access.txt") 

File.foreach('D:/mywork/list.txt') do |target| 
    target = target.strip.sub(/,$/, '') 

    ACCESS_FILES.each do |filename| 
    new_filename = "#{filename}.new" 
    old_filename = "#{filename}.old" 

    File.open(new_filename, 'w') do |fileout| 
     File.foreach(filename) do |line_in| 
     fileout.puts line_in unless line_in[target] 
     end 
    end 

    File.rename(filename, old_filename) 
    File.rename(new_filename, filename) 
    File.delete(old_filename) 
    end 
end 
  • 代わり
    File.open('D:\\mywork\\list.txt').read 
    

    、短く、そしてより簡潔かつ明確な方法は、使用することを次のようになります。

    File.read('D:/mywork/list.txt') 
    

    Rubyは自動的にOSに基づいてパス名の区切り文字を調整してください。読みやすさのために常にスラッシュを使用してください。 the IO documentationから:可能な場合は

Rubyは異なるオペレーティング・システムの規則間のパス名を変換します。たとえば、Windowsシステムでは、ファイル名「/gumby/ruby/test.rb」が「\gumby\ruby\test.rb」として開かれます。

readを使用した場合の問題は、スケーラブルではありません。あなたが長期的な生産システムでこれをやっていて、入力ファイルがTBの範囲に入っていたとしたらどうでしょうか?ファイルを読むことができるまで、システム上の処理を停止します。それをしないでください。

代わりに、foreachを使用して行単位で読み取ることができます。 「Why is "slurping" a file not a good practice?」を参照してください。

Dir.glob("D:/new_work/*-access.txt") do |fn| 

は、その配置はありませんが、細かいですがそれは

value.gsub!(/\r\n?/, "\n") 
    value.each_line do |line| 
     line.chomp! 
  • の必要性を削除します。あなたのファイルで処理されているすべての行が読み込み中で、CPUを無駄にしています。まずそれを読んで値を保存し、その値を繰り返し繰り返します。

  • は再び、

    text = File.read(fn) 
    

    は、スケーラビリティの問題があります。 foreachを使用する方が良い解決策です。再び。 gsubを使用してテキストを置き換える

  • は高速ですが、ライン・バイ・ラインIOが同じように高速であり、完全に問題を回避したときには、スケーラビリティの潜在的な問題を補って余りありません:

    replace = text.gsub(line.strip, "") 
    
  • オープニングより良い練習が何かSに古いファイルの名前を変更し、別の、新しい、ファイルへの書き込みがある

    File.open(fn, "w") { |file| file.puts replace } 
    

    :あなたが読んでいたのと同じファイルへの書き込みは本番環境で起こるのを待って、事故であります新しいファイルの名前を古いファイルの名前に変更します。これにより、コードまたはマシンがセーブ中にクラッシュする場合に備えて、古いファイルが保持されます。それが終わったら、古いファイルを削除しても安全です。詳細は、「How to search file text for a pattern and replace it with a given value」を参照してください。

最終的に入力ファイルからすべてのコンマを削除することをお勧めします。彼らは何も達成しておらず、ファイルを処理するために余分な作業をしているだけです。

+0

@TinMan:ありがとう、あなたが提案したベストプラクティスに間違いなく従います。 – voltas

1

私はあなたのコードを実行しました。私のマシンでは期待通りに動作します。私の推測では、list.txtの各行の末尾にコンマを入れないことです。あなたはとにかくすべての改行を離れてムシャムシャしている、とムシャムシャ食べるには、デフォルトで\r\nを認識することができるのでvalue.gsub!(/\r\n?/, "\n"):余分なchomp!でそれらを削除してください:

value=File.open('D:\\mywork\\list.txt').read 
value.gsub!(/\r\n?/, "\n") 
value.each_line do |line| 
    line.chomp! 
    line.chomp!(",") 
    print "For the string: #{line}" 
    Dir.glob("D:/new_work/*-access.txt") do |fn| 
     print "checking files:#{fn}\n" 
     text = File.read(fn) 
     replace = text.gsub(line.strip, "") 
     File.open(fn, "w") { |file| file.puts replace } 
    end 
end 

ところで、あなたは、この行は必要ありません。

+0

お時間をありがとうございます。とても有難い。 – voltas

関連する問題