一个例子:
def match_environment( filename, check_content = 'test', no_of_lines = 4)
line_pattern = "%1s %5i: %s%"
File.open(filename, "r:windows-1251") do |f|
puts "====File #{f.path}===="
#Contains previous 4 lines
extract = []
hit = 0 #flag to print next lines
f.each_with_index do |line,linno|
linno += 1 #Start line counting with 1
extract.shift if extract.size >= no_of_lines #remove last line
if line.include? ( check_content )
#print previous 4 lines
extract.each_with_index{|pline, index|
puts line_pattern % [ nil, linno - extract.size + index, pline.chomp ]
}
extract = [] #avoid
puts line_pattern % [ '!', linno, line.chomp ] #This line has a hit
hit = no_of_lines #print next four line
else
if hit > 0 #put next lines
puts line_pattern % [ nil, linno,line.chomp ]
hit -= 1
puts ' [...]' if hit == 0
end
extract << line #add actual line
end
end
end #close file
end #match_environment
#Test if we find test anywhere
match_environment( __FILE__, 'test' )
exit #remove to check directory
#loop on directory
Dir['*'].each do |filename|
next unless File.file? filename
match_environment( filename )
end
extract
是一个包含最后 n 行(参数 )的数组no_of_lines
。每个新行都被附加,以前的行被删除。extract
是前 n 行的存储。
hit
是打印下 n 行的计数器。
此解决方案的一个优点:如果您'test'
多次匹配您的搜索模式(在我的示例中是),则之前和之后的四行仅从第一次和最后一次命中开始计算。
line_pattern
是输出的模式(如果该行包含搜索字符串,则为标志,行号为 5 个字符,后跟该行)。
如果我执行脚本,我会得到:
====File test.rb====
1: %
2: %
! 3: def match_environment( filename, check_content = 'test', no_of_lines = 4)%
4: line_pattern = "%1s %5i: %s%"%
5: File.open(filename, "r:windows-1251") do |f|%
6: puts "====File #{f.path}===="%
7: #Contains previous 4 lines%
[...]
33: end #match_environment%
34: %
35: %
! 36: #Test if we find test anywhere%
! 37: match_environment( __FILE__, 'test' )%
38: %
39: exit #remove to check directory%
40: #loop on directory%
41: Dir['*'].each do |filename|%
[...]
备注:match_environment( __FILE__, 'test' )
在脚本文件本身上执行脚本。