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 行を出力するためのカウンターです。

このソリューションの 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' )スクリプト ファイル自体でスクリプトを実行します。

于 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 に答える