I have started learning Ruby and I have come across an annoying problem. I have imported a text file into my program and I want to iterate over the lines in it and print them out to the screen.
When I do this, the console overwrites the last printed out line and writes the new one on top. Why is this happening and how can I solve it?
Here is my code:
passwords = File.open('C:\Users\Ryan\Desktop\pw.txt', 'r')
lines = passwords.gets
for line in lines
puts line
end
Update:
The loop is acting very strange. I put a sleep statement into it and all it did was sleep once then continue to output the lines. I would have expected it to sleep before outputting each line. Example below:
passwords.each do |line|
sleep 1
puts line.chomp
end
Update 2:
I just created a new text file and typed some random stuff into it for testing and it works fine. Looks like the original file had some bad characters/encoding which messed up the printing to the console.
Do you have an EOL (AKA end-of-line) problem? Try this:
passwords = File.open('C:\Users\Ryan\Desktop\pw.txt', 'r')
lines = passwords.gets
lines.each { |line| puts line.chomp }
passwords.close
The chomp call will strip off any \n, \r, or \r\n line endings, then puts will append the native EOL.
File.open('C:\Users\Ryan\Desktop\pw.txt') do |line|
while not line.eof?
puts line.readline.chomp
end
end
or
File.read("file").each { |line| puts line.chomp }
In the end I found out that the text file was the cause of my problem. I created a new one with the same content and it started working how I intended.
Related
I'm a newbie! I have a text file that contains lines and lines of text. I want to try to create a code that only allows the lines that have the phrase "larry.bird" show while the others are deleted. This is my current code...
File.open("HM.txt").each do |line|
puts line
if line.include? "larry.bird"
puts "larye.bird " + line
end
end
File.readlines('HM.txt') do |li|
puts li if (li['larry.bird'])
end
If you can help me out, that would be awesome!
You're pretty close. You're opening and reading the file correctly; you're just accidentally printing every line before performing the check. The puts line on the second line of your code is ensuring that this occurs.
File.open("HM.txt") do |file|
file.each_line do |line|
if line.include? "larry.bird"
puts "larry.bird " + line
end
end
end
We can also shorten one-line if statements in Ruby, using suffix notation that often makes code more concise.
File.open("HM.txt") do |file|
file.each_line do |line|
puts "larry.bird " + line if line.include? "larry.bird"
end
end
This is equivalent to the first example.
I have a file called "file1.txt":
Ruby
programming
is fun
In files.rb, which I'm calling from IRB, I have:
File.open('file1.txt', 'r') do |file|
while line = file.gets
puts "** " + line.chomp + " **" #--> why can't I use file.gets.chomp?
end
end
Why isn't line and file.gets interchangeable on line 3? If I switch line with file.gets, the function does not work, and I am a little bit perplexed considering that
line = file.gets
and
file.gets = line
should be interchangeable, but in this case, it is not as it gives me an error. The function works with line.chomp.
I tried getting rid of the while code block, and simply writing
puts file.gets
and it seems to output a line of code from file1.txt, but does not work inside the while statement on line 3.
I'm not really into Ruby, but I think that is because if you use while line = file.gets, the file.gets return a line and read (and copy to buffer) the next one. In the final iteration, where the while is in the last line, the while line = file.gets will return the last line. But in the while, you call again file.gets, so as there are no more lines in file, it returns an error.
This is untested, but your code can be reduced to:
File.foreach('file1.txt') do |line|
puts "** " + line + " **"
end
I'm trying to read a file into a string. For instance, I tried reading this file:
123456
23456
3456
456
56
6
I tried:
contents = File.open("test.txt", "rb").read
print contents
IO.foreach('test.txt') do |line|
print line
end
File.open('test.txt', 'r').each_line do |line|
print line
end
but I seem to get a single line that will overwrite it's contents with each new line. I get 666666.
The issue has to be the fact that the file is using the CR line terminator (or your terminal is messed up and not responding to LF). print does not go into the new line by default (you should use puts if that's what you want), and each_line does not strip the line terminator. So what happens is, print "123456\r" prints out 123456 and then returns the cursor to the start of the line, without moving to the next line (so the cursor is on 1. Then when you print "23456\r", it will overwrite the first five characters and again come back to the start, the current state being 234566... In the end, 566666 will get overwritten by "6\r" for the final 666666.
Why not try the simple solution
# ruby sample code.
# process every line in a text file with ruby (version 1).
file='test.txt'
File.readlines(file).each do |line|
puts line
end
Second approach
# ruby sample code.
# process every line in a text file with ruby (version 2).
file='test.txt'
f = File.open(file, "r")
f.each_line { |line|
puts line
}
f.close
Answer Source
How can I delete a single, specific line from a text file? For example the third line, or any other line. I tried this:
line = 2
file = File.open(filename, 'r+')
file.each { last_line = file.pos unless file.eof? }
file.seek(last_line, IO::SEEK_SET)
file.close
Unfortunately, it does nothing. I tried a lot of other solutions, but nothing works.
I think you can't do that safely because of file system limitations.
If you really wanna do a inplace editing, you could try to write it to memory, edit it, and then replace the old file. But beware that there's at least two problems with this approach. First, if your program stops in the middle of rewriting, you will get an incomplete file. Second, if your file is too big, it will eat your memory.
file_lines = ''
IO.readlines(your_file).each do |line|
file_lines += line unless <put here your condition for removing the line>
end
<extra string manipulation to file_lines if you wanted>
File.open(your_file, 'w') do |file|
file.puts file_lines
end
Something along those lines should work, but using a temporary file is a much safer and the standard approach
require 'fileutils'
File.open(output_file, "w") do |out_file|
File.foreach(input_file) do |line|
out_file.puts line unless <put here your condition for removing the line>
end
end
FileUtils.mv(output_file, input_file)
Your condition could be anything that showed it was the unwanted line, like, file_lines += line unless line.chomp == "aaab" for example, would remove the line "aaab".
I was trying to use the following code to read lines from a file. But when reading a file, the contents are all in one line:
line_num=0
File.open('xxx.txt').each do |line|
print "#{line_num += 1} #{line}"
end
But this file prints each line separately.
I have to use stdin, like ruby my_prog.rb < file.txt, where I can't assume what the line-ending character is that the file uses. How can I handle it?
Ruby does have a method for this:
File.readlines('foo').each do |line|
puts(line)
end
http://ruby-doc.org/core-1.9.3/IO.html#method-c-readlines
File.foreach(filename).with_index do |line, line_num|
puts "#{line_num}: #{line}"
end
This will execute the given block for each line in the file without slurping the entire file into memory. See: IO::foreach.
I believe my answer covers your new concerns about handling any type of line endings since both "\r\n" and "\r" are converted to Linux standard "\n" before parsing the lines.
To support the "\r" EOL character along with the regular "\n", and "\r\n" from Windows, here's what I would do:
line_num=0
text=File.open('xxx.txt').read
text.gsub!(/\r\n?/, "\n")
text.each_line do |line|
print "#{line_num += 1} #{line}"
end
Of course this could be a bad idea on very large files since it means loading the whole file into memory.
Your first file has Mac Classic line endings (that’s "\r" instead of the usual "\n"). Open it with
File.open('foo').each(sep="\r") do |line|
to specify the line endings.
I'm partial to the following approach for files that have headers:
File.open(file, "r") do |fh|
header = fh.readline
# Process the header
while(line = fh.gets) != nil
#do stuff
end
end
This allows you to process a header line (or lines) differently than the content lines.
It is because of the endlines in each lines.
Use the chomp method in ruby to delete the endline '\n' or 'r' at the end.
line_num=0
File.open('xxx.txt').each do |line|
print "#{line_num += 1} #{line.chomp}"
end
how about gets ?
myFile=File.open("paths_to_file","r")
while(line=myFile.gets)
//do stuff with line
end
Don't forget that if you are concerned about reading in a file that might have huge lines that could swamp your RAM during runtime, you can always read the file piece-meal. See "Why slurping a file is bad".
File.open('file_path', 'rb') do |io|
while chunk = io.read(16 * 1024) do
something_with_the chunk
# like stream it across a network
# or write it to another file:
# other_io.write chunk
end
end