使用Ruby的Enumerable#grep
方法获取匹配行与行号的最佳方法是什么? (因为我们使用-n
或--line-number
使用grep命令切换。)
答案 0 :(得分:8)
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]]
答案 1 :(得分:7)
可能是这样的:
module Enumerable
def lgrep(pattern)
map.with_index.select{|e,| e =~ pattern}
end
end
答案 2 :(得分:4)
这不优雅或高效,但为什么不在grepping之前对行进行编号?
答案 3 :(得分:1)
你可以像Ruby那样在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']]
或者,如果您正在寻找有关在Ruby中编写类似grep的实用程序的技巧。这样的事情应该有效:
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
答案 4 :(得分:1)
>> lines=["one", "two", "tests"]
=> ["one", "two", "tests"]
>> lines.grep(/test/){|x| puts "#{lines.index(x)+1}, #{x}" }
3, tests
答案 5 :(得分:1)
将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
答案 6 :(得分:0)
Tin Man给出的解决方案的修改。此代码段将返回一个散列,其中行号作为键,匹配行作为值。这个也适用于ruby 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"}
答案 7 :(得分:0)
将文字放入档案
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命令类似。
答案 8 :(得分:0)
另一个建议:
lines.find_index{ |l| l=~ regex }
。