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

You can delete a line in a several ways:

  • Simulate deletion. That is, just overwrite line’s content with spaces. Later, when you read and process the file, just ignore such empty lines.

    Pros: this is easy and fast. Cons: it’s not real deletion of data (file doesn’t shrink) and you need to do more work when reading/processing the file.

    Code:

    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"
    
  • Do real deletion. This means that line will no longer exist. So you will have to read next line and overwrite the current line with it. Then repeat this for all following lines until the end of file is reached. This seems to be error prone task (lines of different lengths, etc), so here’s an error-free alternative: open temp file, write to it lines up to (but not including) the line you want to delete, skip the line you want to delete, write the rest to the temp file. Delete the original file and rename temporary one to use its name. Done.

    While this is technically a total rewrite of the file, it does differ from what you asked. The file doesn’t need to be loaded fully to memory. You need only one line at a time. Ruby provides a method for this: IO#each_line.

    Pros: No assumptions. Lines get deleted. Reading code needs not to be altered. Cons: lots more work when deleting the line (not only the code, but also IO/CPU time).

    There is a snippet that illustrates this approach in @azgult’s answer.

Leave a Comment