The title speaks for itself really. I only want to know if it exists, not where it is. Is there a one liner to achieve this?
-
sorry, I like your question, but, please, rename it. I was catched in `detect` function speciality (return first element, not all, uh) – gaussblurinc Mar 25 '14 at 07:37
5 Answers
File.open(filename).grep(/string/)
This loads the whole file into memory (slurps the file). You should avoid file slurping when dealing with large files. That means loading one line at a time, instead of the whole file.
File.foreach(filename).grep(/string/)
It's good practice to clean up after yourself rather than letting the garbage collector handle it at some point. This is more important if your program is long-lived and not just some quick script. Using a code block ensures that the File
object is closed when the block terminates.
File.foreach(filename) do |file|
file.grep(/string/)
end

- 7,131
- 3
- 19
- 43

- 1,169
- 1
- 8
- 9
-
46This actually leaks a file descriptor which could cause a serious problem. Here's a cleaner alternative that will close the file after it's used. `open('some.txt') { |f| f.grep(/string/) }` – Blake Taylor Jun 04 '12 at 00:27
-
14And also leads to load the whole file in memory. `open("some.txt") { |f| f.each_line.detect { |line| /re/.match(line) } }` – rewritten Dec 09 '13 at 10:27
-
2-1 because for some reason it returns false when it should be true. Investigating why. – kgpdeveloper Apr 21 '14 at 06:03
-
2Guys, I see no reason why File#grep would drag file into memory. Can you show me smth about that in docs? – Nakilon May 24 '16 at 17:11
-
I would give priority to multi-line queries over worrying about running out of memory when loading a file for parsing. If you're parsing large files on small/embedded systems, you've got a whole host of optimization concerns that fall outside typical parsing requirements. I would assume what you're parsing for is fine per-line is if I had intrinsic information to confirm it, but only then. – kayleeFrye_onDeck Jun 05 '17 at 19:59
-
This code of yours does not leak file descriptors: `File.foreach(filename).grep(/string/)`. The file gets opened and closed within the call to `grep`. If you don't believe it, try printing some messages immediately before and after `grep` and use `strace ./your_program.rb` to see what happens between those two prints. – David Grayson Feb 14 '18 at 07:07
-
I have not found specifications for a File.grep or String.grep method. What version of ruby is this? – Julien Lamarche Feb 07 '19 at 19:27
-
@JulienLamarche `IO::foreach` and `Enumerable#grep` - https://ruby-doc.org/core-2.5.0/IO.html#method-c-foreach - https://ruby-doc.org/core-2.5.0/Enumerable.html#method-i-grep – go2null Apr 28 '19 at 21:08
-
Isn't "slurping" actually the complete opposite? Meaning, reading the entire file in memory. – Iulian Onofrei Jan 13 '20 at 16:00
-
grep for foo OR bar OR baz, stolen from ruby1line.txt.
$ ruby -pe 'next unless $_ =~ /(foo|bar|baz)/' < file.txt

- 94,654
- 45
- 215
- 319
-
Link seems broken, is this a mirror? http://www.das-labor.org/svn/ruby/sandbox/oneliner.txt – Dimitrios Mistriotis Nov 03 '13 at 14:13
-
1Ruby oneliner http://reference.jumpingmonkey.org/programming_languages/ruby/ruby-one-liners.html#h5 @dimitris mistriotis – Sanjeev Apr 29 '14 at 06:42
If your OS has a grep package, you could use a system call:
system("grep meow cat_sounds.txt")
This will return true if grep
returns anything, false if it does not.
If you find yourself on a system with grep
, you may find this is the "best" way because Ruby can be slow when it comes to file operations.

- 158,662
- 42
- 215
- 303

- 106,965
- 23
- 235
- 261
-
2
-
16
-
Funily enough it was a rakefile I was creating when I came up with this question, so I can even re-factor this to sh "grep meow cat_sounds.txt" :-) – ChrisInCambo Mar 11 '09 at 05:36
-
And it still returns true / false? Cool! http://rake.rubyforge.org/classes/FileUtils.html#M000018 haha! The example is even grepping! – Ryan Bigg Mar 11 '09 at 05:41
-
1What does sanity have to do with the fact that not all OSes have a "grep" command? – bk1e Mar 11 '09 at 05:53
-
1I find it insane that people try to run Ruby on Windows, given all the pitfalls. – Ryan Bigg Mar 11 '09 at 06:00
-
Ruby works on Windows quite well actually. But then you have the gems....*grimace of pain*. Still, it's my language of choice for system scripts. – SimonV Mar 11 '09 at 16:50
-
Do people actually use Windows in production? I think that's insane. +1 for this answer. – kgpdeveloper Apr 21 '14 at 04:34
Well it seems eed3si9n has the one liner down, here's the longer solution:
f = File.new("file.txt")
text = f.read
if text =~ /string/ then
#relevant code
end

- 23,735
- 11
- 56
- 82
-
-
-
This reads in entire file and is not as efficient as other line-oriented commands in this post – Christopher Kuttruff Feb 03 '19 at 08:19
This reads the file only to the first appearance of 'string' and processes it line by line - not reading the whole file at once.
def file_contains_regexp?(filename,regexp)
File.foreach(filename) do |line|
return true if line =~ regexp
end
return false
end

- 33,354
- 5
- 79
- 106