0

I am trying to create a ruby tool that goes through a file looking for a certain string, and if it finds that word than it stores it in a variable. If NOT then it prints “word not found” on the console. Is this possible? How can i code this?

2 Answers2

1

You can use File#open method and readlinesmethod like this.

test.txt

This is a test string.
Lorem imsum.
Nope.

code

def get_string_from_file(string, file_path)
  File.open(file_path) do |f|
    f.readlines.each { |line| return string if line.include?(string) }
  end
  nil
end

file_path = './test.txt'
var = get_string_from_file('Lorem', file_path)
puts var || "word not found"
# => "Lorem"

var = get_string_from_file('lorem', file_path)
puts var || "word not found"
# => "word not found"

I hope this heps.

Lukas Baliak
  • 2,849
  • 2
  • 23
  • 26
0

Here's few examples of how you could find a certain word in a text file using IO from the Ruby core: http://ruby-doc.org/core-2.3.1/

In find_word_in_text_file.rb:

# SETUP
#
filename1 = 'file1.txt'
filename2 = 'file2.txt'

body1 = <<~EOS
  PHRASES

  beside the point
  irrelevant.

  case in point
  an instance or example that illustrates what is being discussed: the “green revolution” in agriculture is a good case in point.

  get the point
  understand or accept the validity of someone's idea or argument: I get the point about not sending rejections.

  make one's point
  put across a proposition clearly and convincingly.

  make a point of
  make a special and noticeable effort to do (a specified thing): she made a point of taking a walk each day.
EOS

body2 = <<~EOS
  nothing to see here
  or here
  or here
EOS

# write body to file
File.open(filename1, 'w+') {|f| f.write(body1)}

# write file without matching word
File.open(filename2, 'w+') {|f| f.write(body2)}

# METHODS
#
# 1) search entire file as one string
def file_as_string_rx(filename, string)

  # http://ruby-doc.org/core-2.3.1/Regexp.html#method-c-escape
  # http://ruby-doc.org/core-2.3.1/Regexp.html#method-c-new
  rx = Regexp.new(Regexp.escape(string), true) # => /whatevs/i

  # read entire file to string
  # http://ruby-doc.org/core-2.3.1/IO.html#method-i-read
  text = IO.read(filename)

  # search entire file for string; return first match
  found_word = text[rx]

  # print word or default string
  puts found_word || "word not found"
  # —OR—
  #STDOUT.write found_word || "word not found"
  #STDOUT.write "\n"
end

# 2) search line by line
def line_by_line_rx(filename, string)

  # http://ruby-doc.org/core-2.3.1/Regexp.html#method-c-escape
  # http://ruby-doc.org/core-2.3.1/Regexp.html#method-c-new
  rx = Regexp.new(Regexp.escape(string), true) # => /whatevs/i

  # create array to store line numbers of matches
  matches_array = []

  # search each line for string
  # http://ruby-doc.org/core-2.3.1/IO.html#method-c-readlines
  #lines = IO.readlines(filename)
  #
  # http://ruby-doc.org/core-2.3.1/Enumerable.html#method-i-each_with_index
  # http://stackoverflow.com/a/5546681/1076207
  #   "Be wary of "slurping" files. That's when you
  #   read the entire file into memory at once.
  #   The problem is that it doesn't scale well.
  #lines.each_with_index do |line,i|
  #
  # —OR—
  #
  # http://ruby-doc.org/core-2.3.1/IO.html#method-c-foreach
  i = 1
  IO.foreach(filename) do |line|

    # add line number if match found within line
    matches_array.push(i) if line[rx]

    i += 1
  end

  # print array or default string
  puts matches_array.any? ? matches_array.inspect : "word not found"
  # —OR—
  #STDOUT.write matches_array.any? ? matches_array.inspect : "word not found"
  #STDOUT.write "\n"
end

# RUNNER
#
string = "point"

puts "file_as_string_rx(#{filename1.inspect}, #{string.inspect})"
file_as_string_rx(filename1, string)

puts "\nfile_as_string_rx(#{filename2.inspect}, #{string.inspect})"
file_as_string_rx(filename2, string)

puts "\nline_by_line_rx(#{filename1.inspect}, #{string.inspect})"
line_by_line_rx(filename1, string)

puts "\nline_by_line_rx(#{filename2.inspect}, #{string.inspect})"
line_by_line_rx(filename2, string)

# CLEANUP
#
File.delete(filename1)
File.delete(filename2)

Command line:

$ ruby find_word_in_text_file.rb
file_as_string_rx("file1.txt", "point")
point

file_as_string_rx("file2.txt", "point")
word not found

line_by_line_rx("file1.txt", "point")
[3, 6, 7, 9, 10, 12, 15, 16]

line_by_line_rx("file2.txt", "point")
word not found
SoAwesomeMan
  • 3,226
  • 1
  • 22
  • 25