Ruby, эквивалентный “grep-C 5” для получения контекста строк вокруг соответствия?

Я искал это немного, но я должен использовать неправильные термины - рубин имеет путь к grep для string/regex и также возвращает окружение 5 строк (выше и ниже)? Я знаю, что мог просто звонить "grep -C 5 ..."или даже запишите мой собственный метод, но кажется, что что-то рубиновое имело бы, и я просто не использую правильные критерии поиска.

6
задан Brian Tompsett - 汤莱恩 5 June 2015 в 22:13
поделиться

2 ответа

Вы можете сделать это с помощью регулярного выражения. Вот строка, которую мы хотим найти:

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 для меня "\ n", но для вас это может быть "\ r \ n". Я вставлю его в константу:

EOL = '\n'

Чтобы упростить регулярное выражение, мы определим шаблон для «контекста» только один раз:

CONTEXT_LINES = 2
CONTEXT = "((?:.*#{EOL}){#{CONTEXT_LINES}})"

И мы будем искать любую строку, содержащую слово «пятая». Обратите внимание, что это регулярное выражение должно захватить всю строку, включая конец строки, чтобы оно работало:

regexp = /.*fifth.*#{EOL}/

Наконец, выполните поиск и покажите результаты:

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"
6
ответ дан 16 December 2019 в 21:36
поделиться

Я не думаю, что вы можете передавать args в grep; основываясь на api.

Вы всегда можете написать метод. Что-то вроде этого:

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
0
ответ дан 16 December 2019 в 21:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: