有没有办法删除文本文件中与特定文本匹配的行?

Is there a way to delete a line in a text file if it matches a specific text?

我的文本文件包含一个 email/password 列表来设置帐户。一旦我使用了电子邮件和密码组合,我想将其从文本文件中删除。

我的文本文件如下所示:

email,pass
email,pass
etc..

一旦我使用了 e/p 组合,我想将其从文件中删除:

File.open("yahoo_accounts.txt") do |email|
  email.each do |item|
    email, password = item.chomp.split(',')
    emails << email 
    passwords << password
    emails.zip(passwords) { |name, pass| 
        browser = Watir::Browser.new :ff

        #using the email and pass

        File.open("yahoo_accounts.txt", "w") do |out_file|
            File.foreach("yahoo_accounts.txt","r") do |line|
                out_file.puts line unless line == '#{name},#{pass}'
            end
        end
        browser.close
    end
end

当我尝试从文件中删除它们时出现问题。我得到一个 "browser.rb:382:in `assert_exists': browser was closed (Watir::Exception::Error)", 但这可能只是浏览器关闭。

如果一开始就提取了所有 e/p(意味着没有任何内容可删除),我如何循环它以继续进行,而不是在第一个 zip 循环后以错误结束?

你不能像那样同时写入和读取同一个文件;您写的第一行会破坏文件的其余部分,因此您将无法再阅读它。

您应该在阅读这些行时将更改写入临时文件,然后在末尾将临时文件移动到原始文件。类似于:

require 'tempfile'
require 'fileutils'

temp_file = Tempfile.new('foo')
begin
  File.open("yahoo_accounts.txt", 'r') do |file|
    file.each_line do |line|
      temp_file.puts line unless line == '#{name},#{pass}'
    end
  end
  temp_file.close
  FileUtils.mv(temp_file.path, "yahoo_accounts.txt")
ensure
  temp_file.close
  temp_file.unlink
end

如果文件不大,可以读入一个数组,修改数组,然后将数组写入文件,覆盖之前的内容。

代码

def remove_lines(fname, user_name, password)
  IO.write(fname, IO.read(fname).gsub(/^#{user_name},#{password}\n/, ''))
end

例子

让我们创建一些数据:

text =<<_
Bubba,boar
Henrietta,vespa
Luigi,pink
Bubba,boar
Luigi,mauve
_
  #=> "Bubba,boar\nHenrietta,vespa\nLuigi,pink\nBubba,boar\nLuigi,mauve\n"

并将其写入文件:

FName = "tmp"
IO.write(FName, text)
  #=> 61

我们可以确认我们写入文件的内容:

IO.read(FName)
  #=>  "Bubba,boar\nHenrietta,vespa\nLuigi,pink\nBubba,boar\nLuigi,mauve\n"

现在删除 user_name/password #=> Bubba/boar 的行:

remove_lines(FName, "Bubba", "boar")
  #=> 39

让我们通过检查 FName:

来确认它是否有效
IO.read(FName)
  #=> "Henrietta,vespa\nLuigi,pink\nLuigi,mauve\n"

后记

如果在将数组写入文件时出现问题,您可能会同时丢失旧文件和新文件。因此,将数组写入临时文件,然后删除原始文件,然后将临时文件重命名为原始文件的名称通常是一种很好的做法。