1

我的脚本搜索文件,在日志中找到一个条目并打印相应的行,我想看到的是匹配周围的几行,以便查看之前发生的事情

files=Dir.open(Dir.pwd)
files.each do |li|
  next unless File.file? li
  f = File.open(li, "r:windows-1251")
  if f.each do |line|
    next unless line.include? (tag_466) or line.include?(tag_1004)
    a=[]
    a << ["1.#{MAT_1}".aster.console_green, line, "\n"] if line =~ /#{MAT_1}/
    a << ["2.#{MAT_2}".aster.console_green, line, "\n"] if line =~ /#{MAT_2}/
    puts a
  end
end
4

2 回答 2

1

一个例子:

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' )在脚本文件本身上执行脚本。

于 2012-06-18T10:36:21.457 回答
0

您可以通过多个步骤来完成:

  1. 将文件读入一个Array
  2. 在该数组中查找匹配的行索引
  3. 实现一个print_line(ary, index, context)打印行index-context..index+context并为找到的每个索引调用它的方法
于 2012-06-18T10:15:43.597 回答