I've searched for this a bit but I must be using the wrong terms - does ruby have a way to grep for a string/regex and also return the surrounding 5 lines (above and below)? I know I could just call "grep -C 5 ..."
or even write my own method, but it seems like something ruby would have and I'm just not using the right search terms.
views:
189answers:
2
A:
I don't think you can supply args to grep; based on the api.
You could always write a method. Something along the lines of this:
def new_grep(enum, pattern, lines)
values = enum.grep(/pattern/).map do |x|
index = enum.index(x)
i = (index - lines < 0) ? 0 : index - lines
j = (index + lines >= enum.length) ? enum.length-1 : index + lines
enum[i..j]
end
return values.flatten.uniq
end
Pran
2010-05-03 20:41:33
This one might work too, but I found Wayne's answer to be more along the lines of what I wanted.
wonderfulthunk
2010-05-04 19:44:21
+3
A:
You can do it with a regular expression. Here's the string we want to search:
s = %{The first line
The second line
The third line
The fourth line
The fifth line
The sixth line
The seventh line
The eight line
The ninth line
The tenth line
}
EOL is "\n" for me, but for you it might be "\r\n". I'll stick it in a constant:
EOL = '\n'
To simplify the regular expression, we'll define the pattern for "context" just once:
CONTEXT_LINES = 2
CONTEXT = "((?:.*#{EOL}){#{CONTEXT_LINES}})"
And we'll search for any line containing the word "fifth." Note that this regular expression must grab the entire line, including the end-of-line, for it to work:
regexp = /.*fifth.*#{EOL}/
Finally, do the search and show the results:
s =~ /^#{CONTEXT}(#{regexp})#{CONTEXT}/
before, match, after = $1, $2, $3
p before # => "The third line\nThe fourth line\n"
p match # => "The fifth line\n"
p after # => "The sixth line\nThe seventh line\n"
Wayne Conrad
2010-05-03 22:02:45
This was great, thanks! It works like a charm - I had to go back and re-read that the end-of-line must be included in the regular expression that I'm searching for, I missed that when I initially tried this.
wonderfulthunk
2010-05-04 19:43:13
This should work: /.*fifth.*[#{EOL}]*/See http://rubular.com/r/skalXLBXcQ
Ramon Tayag
2010-10-29 00:21:54