Что может быть лучшим способом получения совпадающих строк с номерами строк с использованием метода Ruby Enumerable#grep
. (поскольку мы используем переключатель -n
или --line-number
с командой grep).
Ruby grep с номером строки
Ответ 1
Enumerable # grep не позволяет делать это, по крайней мере, по умолчанию. Вместо этого я придумал:
text = 'now is the time
for all good men
to come to the aid
of their country'
regex = /aid/
hits = text.lines.with_index(1).inject([]) { |m,i| m << i if (i[0][regex]); m }
hits # => [["to come to the aid\n", 3]]
Ответ 2
может быть что-то вроде этого:
module Enumerable
def lgrep(pattern)
map.with_index.select{|e,| e =~ pattern}
end
end
Ответ 3
Это не изящно или эффективно, но почему бы просто не пронумеровать строки перед grepping?
Ответ 4
Вы можете уничтожить его в Ruby 1.8.6 следующим образом:
require 'enumerator'
class Array
def grep_with_index(regex)
self.enum_for(:each_with_index).select {|x,i| x =~ regex}
end
end
arr = ['Foo', 'Bar', 'Gah']
arr.grep_with_index(/o/) # => [[0, 'Foo']]
arr.grep_with_index(/a/) # => [[1, 'Bar'], [2, 'Gah']]
Или, если вы ищете советы по написанию grep-подобной утилиты в Ruby. Что-то вроде этого должно работать:
def greplines(filename, regex)
lineno = 0
File.open(filename) do |file|
file.each_line do |line|
puts "#{lineno += 1}: #{line}" if line =~ regex
end
end
end
Ответ 5
>> lines=["one", "two", "tests"]
=> ["one", "two", "tests"]
>> lines.grep(/test/){|x| puts "#{lines.index(x)+1}, #{x}" }
3, tests
Ответ 6
Чтобы размять ответы Tin Man и ghostdog74
text = 'now is the time
for all good men
to come to the aid
of their country'
regex = /aid/
text.lines.grep(/aid/){|x| puts "#{text.lines.find_index(x)+1}, #{x}" }
# => 3, to come to the aid
Ответ 7
Модификация решения, заданного Tin Man. Этот фрагмент возвращает хеш с номерами строк в виде ключей и соответствующими строками в качестве значений. Это также работает в рубине 1.8.7.
text = 'now is the time
for all good men
to come to the aid
of their country'
regex = /aid/
hits = text.lines.each_with_index.inject({}) { |m, i| m.merge!({(i[1]+1) => i[0].chomp}) if (i[0][regex]); m}
hits #=> {3=>"to come to the aid"}
Ответ 8
Поместите текст в файл
test.log
now is the time
for all good men
to come to the aid
of their country
Командная строка (альтернатива команде grep или awk)
ruby -ne ' puts $_ if $_=~/to the/' test.log
Попробуйте также
ruby -na -e ' puts $F[2] if $_=~/the/' test.log
Аналогично
ruby -na -e ' puts $_.split[2] if $_=~/the/' test.log
Это похоже на команду awk.