例:
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 行を出力するためのカウンターです。
このソリューションの 1 つの利点: 検索パターン (私の例では'test'
) に複数回一致する場合、前後の 4 行は最初と最後のヒットからのみカウントされます。
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' )
スクリプト ファイル自体でスクリプトを実行します。