Benjamin
Benjamin

Reputation: 561

Reading specific lines from an external file in ruby IO

I have this code:

File.foreach("testfile.txt") { |line| print line }
lines = File.readlines("testfile.txt")
lines.each { |line| print line }

Ex. how could I edit this to get a specific line from testfile.txt ?

$text2 = gets("some code to give me text on line 2 from textfile.txt").chomp

So, I want to run a program that searches for 4 different variables that are editable by anyone. These will be in a separate file and thus the code will not have to be rewritten in order to change the test for a new set of search cases.

Say I have a document (I suppose text is easiest but am probably wrong) that looks like this:

Tea

Coffee

Hot Chocolate

Cookies

That will be all that is in the file. And another file(.rb) pulls these variables and searches for them in Google or whatever. If the code reads in bytes then I wouldn't be able to change the variables to anything longer or shorter.

It would be feasible to have the document say

1:Tea

2:Coffee

3:Hot Chocolate

4:Cookies

So long as the code would only pull out the "Tea" or "coffee" and not the preceding number.

Upvotes: 3

Views: 4491

Answers (4)

Kelvin
Kelvin

Reputation: 20857

It sounds like you don't want to return a line that matches a certain pattern, but you want to grab by line number.

Solution 1:

def read_line_number(filename, number)
  return nil if number < 1
  line = File.readlines(filename)[number-1]
  line ? line.chomp : nil
end

Solution 2a - a bit more efficient because it doesn't try to read entire file:

require 'english'
def read_line_number_1a(filename, number)
  found_line = nil
  File.foreach(filename) do |line|
    if $INPUT_LINE_NUMBER == number
      found_line = line.chomp
      break
    end
  end
  found_line
end

Solution 2b - also efficient, but in a more functional style (though I haven't checked whether detect will read to end-of-file)

def read_line_number(filename, match_num)
  found_line, _idx =
    File.enum_for(:foreach, filename).each_with_index.detect do |_cur_line, idx|
      cur_line_num = idx+1
      cur_line_num == match_num
    end
  found_line.chomp
end

Usage:

text = read_line_number("testfile.txt", 2)

Upvotes: 5

Nando
Nando

Reputation: 1

def read_line_number(filename, number)
f = File.open(filename)
l = nil
begin
  number.times do 
  l = f.readline.chomp
  end
rescue
puts "End of file reached"
else
f.close unless f.nil?
return l  
end
end

Upvotes: 0

Benjamin
Benjamin

Reputation: 561

The solution I have is:

My testfile.txt reads

Yes
Yes is does
Man this is awesome

my .rb file reads

a = IO.readlines("testfile.txt").grep(/\w+/)
puts "does it work...."
sleep 2
puts a[2]
sleep 10

Upvotes: 0

mikezter
mikezter

Reputation: 2463

You would want to use lines.grep "some string". Or just lines[x] if you know exactly which line number x you want.

Upvotes: 0

Related Questions