13

How can I open a file and search for a word inside it using Ruby?

tshepang
  • 12,111
  • 21
  • 91
  • 136
Markus
  • 161
  • 1
  • 1
  • 3
  • 2
    have you at least done a search? – Mitch Wheat Dec 13 '09 at 13:50
  • 1
    @Mitch: He doesn't need to do a search, because he has actually asked esentially the exact same question twice before. – Jörg W Mittag Dec 13 '09 at 14:40
  • 4
    @Whoever voted to close this: the question may annoy you (because you want the OP to search or read a book or whatever), but it is a clear and real programming question. Vote it down if you like, but I can't see how it violates SO's guidelines for questions. It's specific, at least one programmer is bound to be interested and the writing is clear and simple (setting grammar aside). The 'detailed' requirement is tricky, but I think this question is as detailed as it needs to be: How do I do *this specific thing* with *this twist*, using *this programming language*. – Telemachus Dec 13 '09 at 15:23
  • @Jorg: He probably doesn't realize that reading a file on disc is the same in principle as reading a webpage you grab programatically. A lot of people don't see this connection at first. You need to learn that whole *nix-y thing about "it's all just files." – Telemachus Dec 13 '09 at 15:24
  • 1
    This is the third time you are asking the same question with 2 different accounts! – Simone Carletti Dec 13 '09 at 15:32
  • @Jörg I can only see two questions in total by Markus, unless one's been deleted. Where's the third? – Andrew Grimm Dec 13 '09 at 22:03
  • @myself: Oh: there's two accounts with the name Markus. http://stackoverflow.com/users/228343/markus and http://stackoverflow.com/users/230642/markus – Andrew Grimm Dec 13 '09 at 22:06

4 Answers4

32

All presented solution have a time complexity of O(n). For simplicity I use String#include? to check for the word. This could be done instead with a regular expression in the form string=~ regex.

Read the complete file and search in it.

File.read(filename).include?(word)

If your file is very large, this is not an optimal solution, as you would read the complete file into memory and start searching afterwards. Your memory complexity is O(n)

Read the file line by line and search in each line

File.open(filename) do |f|
  f.any? do |line|
    line.include?(word)
  end
end

If your file is very large, but you know your lines are upperbounded by a constant value, you now have a memory complexity of O(1).

Read chunks of the file and search in it

File.open(filename) do |f|
  tmp= f.read(1024)
  next true if tmp.include?(word)
  until f.eof?
    tmp= tmp[(-1*word.size)..-1] + f.read(1024)
    next true if tmp.include?(word)
  end
  next false
end

In this variant, we are reading equaly sized chunks from the file. So no matter what the conditions of the file are, our memory complexity is O(1)

amnn
  • 3,657
  • 17
  • 23
johannes
  • 7,262
  • 5
  • 38
  • 57
  • Wow, great explanation with much more depth than the original question. Thanks a lot for mini tutorial :) – Nikos D Dec 13 '09 at 14:08
  • In the 3rd/chunked solution, couldn't that fail if the word you're searching for spanned the boundary of the 1024 bytes you're reading at a time? – canhazbits Feb 18 '15 at 21:16
  • 1
    @canhazbits line 5 keeps the end of the previous chunk to handle the case where the searched for word spans the chunk boundary. How much is kept depends on the word size. – johannes Feb 27 '15 at 20:24
3

Something like this might help:

def word_exists_in_file
   f = File.open("your_file.txt") #opens the file for reading
   f.each do line
      print line
      if line.match /your_word_to_match/
         return true
      end
   end
   false
end
Ben Scheirman
  • 40,531
  • 21
  • 102
  • 137
1
File.readlines(file).each {|l| l.grep(/#{exp_search}/).each {|r| puts file + ' : ' + r}}
ennuikiller
  • 46,381
  • 14
  • 112
  • 137
0

Try gem 'search_in_file', it helps you to search word of phrase in specified file or in many files by path

bmalets
  • 3,207
  • 7
  • 35
  • 64