簡體   English   中英

如何使用Ruby刪除文本文件中間的數據行

[英]How do I remove lines of data in the middle of a text file with Ruby

我知道如何寫入文件,並從文件中讀取,但我不知道如何修改文件,除了將整個文件讀入內存,操作它,並重寫整個文件。 對於大文件,這不是很有效率。

我真的不知道追加和寫的區別。

例如

如果我有一個文件包含:

Person1,will,23
Person2,Richard,32
Person3,Mike,44

我怎么能只刪除包含Person2的行?

您可以通過多種方式刪除一行:

  • 模擬刪除。 也就是說,只用空格覆蓋行的內容。 稍后,當您閱讀並處理文件時,只需忽略這些空行。

    優點 :這很簡單快捷。 缺點 :它不是真正的數據刪除(文件不縮小),你需要在閱讀/處理文件時做更多的工作。

    碼:

     f = File.new(filename, 'r+') f.each do |line| if should_be_deleted(line) # seek back to the beginning of the line. f.seek(-line.length, IO::SEEK_CUR) # overwrite line with spaces and add a newline char f.write(' ' * (line.length - 1)) f.write("\\n") end end f.close File.new(filename).each {|line| p line } # >> "Person1,will,23\\n" # >> " \\n" # >> "Person3,Mike,44\\n" 
  • 做真正的刪除。 這意味着該行將不再存在。 因此,您必須閱讀下一行並用它覆蓋當前行。 然后對所有后續行重復此操作,直到到達文件末尾。 這似乎是容易出錯的任務(不同長度的行等),所以這里是一個無錯誤的替代方法:打開臨時文件,寫入它排隊(但不包括)你要刪除的行,跳過你的行想要刪除,將其余部分寫入臨時文件。 刪除原始文件並重命名臨時文件以使用其名稱。 完成。

    雖然這在技術上是對文件的完全重寫,但它確實與您的要求不同。 該文件不需要完全加載到內存。 您一次只需要一行。 Ruby提供了一種方法: IO#each_line

    優點 :沒有假設。 線條被刪除。 閱讀代碼不需要改變。 缺點 :刪除行時不僅需要更多工作(不僅是代碼,還有IO / CPU時間)。

    在@ azgult的回答中有一個片段說明了這種方法。

由於文件基本上是作為連續的數據塊保存到磁盤上,因此刪除它的任何部分都需要至少重寫之后的內容。 這實際上意味着 - 正如你所說 - 它對於大文件來說並不是特別有效。 因此,限制文件大小通常是一個好主意,這樣就不會出現這樣的問題。

一些“妥協”解決方案可能是將文件逐行復制到第二個文件,然后移動它以替換第一個文件。 這樣可以避免將文件加載到內存中,但不會避免任何硬盤訪問:

require 'fileutils'

open('file.txt', 'r') do |f|
  open('file.txt.tmp', 'w') do |f2|
    f.each_line do |line|
       f2.write(line) unless line.start_with? "Person2"
    end
  end
end
FileUtils.mv 'file.txt.tmp', 'file.txt'

更有效的是讀寫打開文件並跳到你要刪除的位置,然后將其余的數據移回 - 但這會產生一些非常難看的代碼(我不能被要求現在就這樣做)。

您可以打開文件並逐行讀取,將要保留的行附加到新文件中。 這使您可以最大程度地控制保留哪些行,而不會破壞原始文件。

File.open('output_file_path', 'w') do |output| # 'w' for a new file, 'a' append to existing
  File.open('input_file_path', 'r') do |input|
    line = input.readline
    if keep_line(line) # logic here to determine if the line should be kept
      output.write(line)
    end
  end
end

如果您知道要刪除的塊的開頭和結尾的位置,則可以打開文件,讀取開頭,然后搜索結束並繼續閱讀。

查找read方法的參數,並閱讀有關在此處搜索的內容:

http://ruby-doc.org/core-2.0/IO.html#method-i-read

在這里閱讀:

File.open('output.txt', 'w') do |out_file|
  File.open('input.txt', 'r').each do |line|
    out_file.print line.sub('Person2', '')
  end
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM