繁体   English   中英

如何在Ruby中的匹配行周围打印几行?

[英]How to print several lines around a matched line in Ruby?

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

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

一个例子:

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

您可以分多个步骤进行操作:

  1. 将文件读入Array
  2. 在该数组中找到匹配的行索引
  3. 实现方法print_line(ary, index, context)打印行index-context..index+context并为找到的每个索引调用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM