问题
I have a text file (a.txt) that looks like the following.
open
close
open
open
close
open
I need to find a way to replace the 3rd line with "close". I did some search and most method involve searching for the line than replace it. Can't really do it here since I don't want to turn all the "open" to "close".
Essentially (for this case) I'm looking for a write version of IO.readlines("./a.txt") [2].
回答1:
How about something like:
lines = File.readlines('file')
lines[2] = 'close' << $/
File.open('file', 'w') { |f| f.write(lines.join) }
回答2:
str = <<-_
my
dog
has
fleas
_
FNameIn = 'in'
FNameOut = 'out'
First, let's write str
to FNameIn
:
File.write(FNameIn, str)
#=> 17
Here are a couple of ways to replace the third line of FNameIn
with "had" when writing the contents of FNameIn
to FNameOut
.
#1 Read a line, write a line
If the file is large, you should read from the input file and write to the output file one line at a time, rather than keeping large strings or arrays of strings in memory.
fout = File.open(FNameOut, "w")
File.foreach(FNameIn).with_index { |s,i| fout.puts(i==2 ? "had" : s) }
fout.close
Let's check that FNameOut
was written correctly:
puts File.read(FNameOut)
my
dog
had
fleas
Note that IO#puts writes a record separator if the string does not already end with a record separator.1. Also, if fout.close
is omitted FNameOut
is closed when fout
goes out of scope.
#2 Use a regex
r = /
(?:[^\n]*\n) # Match a line in a non-capture group
{2} # Perform the above operation twice
\K # Discard all matches so far
[^\n]+ # Match next line up to the newline
/x # Free-spacing regex definition mode
File.write(FNameOut, File.read(FNameIn).sub(r,"had"))
puts File.read(FNameOut)
my
dog
had
fleas
1 File.superclass #=> IO
, so IO
's methods are inherited by File
.
来源:https://stackoverflow.com/questions/35958632/replace-a-specific-line-in-a-file-using-ruby