如何将File line reader推进到下一行?

时间:2021-10-08 11:19:32

I have a scenario in a script I'm writing where I do:

我在脚本中有一个场景,我在写我所做的事情:

full gist: https://gist.github.com/calebtote/8337449

全部要点:https://gist.github.com/calebtote/8337449

sourceFile.each_line do |line|
    if (line.start_with?(*criteria)) then 
        buffer << line
        buffer << "\n\n"
    end
end

However, I want to add additional criteria to this that aren't as straightforward. For example, I would like to be able to parse exceptions, which may not be single line events.. so in pseudo, I want something similar to:

但是,我想为此添加额外的标准并不是那么简单。例如,我希望能够解析异常,这可能不是单行事件..所以在伪,我想要类似的东西:

sourceFile.each_line do |line|
    if (line.start_with?(*criteria)) then 
        buffer << line
        buffer << "\n\n"
    elsif (line.start_with?("Exception:")) then
            buffer << line
            line.advance #<- not sure what do to here
            while !line.chomp.empty?
    end
end

Edit 1:

Clarification on expected inputs / outputs:

澄清预期的投入/产出:

# input file
13:37:09:299         DBA               20      
SELECT Name from Table


Exception: Error code 50100
Description: Bad stuff!
Line number 243, File name: myfile.cpp
Time: 12/31/2013 08:24:20

13:37:09:301         Identity_FW       10      
In ApplicationIdentity::operator==

#output file
Exception: Error code 50100
Description: Bad stuff!
Line number 243, File name: myfile.cpp
Time: 12/31/2013 08:24:20

2 个解决方案

#1


1  

If that's all you're doing, there's no need to parse line-by-line.

如果这就是你所做的一切,那就不需要逐行解析了。

destFile.puts sourceFile.read.split("\n\n").select { |x| x =~ /^Exception: / }

#2


0  

Ruby's Enumerable has a nice method called slice_before that makes this sort of task easy.

Ruby的Enumerable有一个很好的方法叫做slice_before,这使得这类任务很容易。

Starting with a "test.log" that looks like:

从“test.log”开始,看起来像:

#begin log data above this

Exception: Error code 50100
Description: Bad stuff!
Line number 243, File name: myfile.cpp
Time: 12/31/2013 08:24:20

#continue log
#continue log
#continue log
#continue log

Exception: Error code 50100
Description: Bad stuff!
Line number 243, File name: myfile.cpp
Time: 12/31/2013 08:24:20

#continue log
#continue log
#continue log
#continue log

This code will break it down into chunks you can parse easily:

此代码将其分解为可以轻松解析的块:

File.foreach('test.log').slice_before(/^\s*$/).to_a 
# => [["#begin log data above this\n"],
#     ["\n",
#      "Exception: Error code 50100\n",
#      "Description: Bad stuff!\n",
#      "Line number 243, File name: myfile.cpp\n",
#      "Time: 12/31/2013 08:24:20\n"],
#     ["\n",
#      "#continue log\n",
#      "#continue log\n",
#      "#continue log\n",
#      "#continue log\n"],
#     ["\n",
#      "Exception: Error code 50100\n",
#      "Description: Bad stuff!\n",
#      "Line number 243, File name: myfile.cpp\n",
#      "Time: 12/31/2013 08:24:20\n"],
#     ["\n",
#      "#continue log\n",
#      "#continue log\n",
#      "#continue log\n",
#      "#continue log\n"]]

You don't need to_a to loop over it. Do something like:

你不需要to_a来循环它。做类似的事情:

File.foreach('test.log').slice_before(/^\s*$/).each do |chunk|
  # process the chunk
end 

Instead of foreach you can use readlines. The end result should be the same.

而不是foreach,你可以使用readlines。最终结果应该是相同的。

#1


1  

If that's all you're doing, there's no need to parse line-by-line.

如果这就是你所做的一切,那就不需要逐行解析了。

destFile.puts sourceFile.read.split("\n\n").select { |x| x =~ /^Exception: / }

#2


0  

Ruby's Enumerable has a nice method called slice_before that makes this sort of task easy.

Ruby的Enumerable有一个很好的方法叫做slice_before,这使得这类任务很容易。

Starting with a "test.log" that looks like:

从“test.log”开始,看起来像:

#begin log data above this

Exception: Error code 50100
Description: Bad stuff!
Line number 243, File name: myfile.cpp
Time: 12/31/2013 08:24:20

#continue log
#continue log
#continue log
#continue log

Exception: Error code 50100
Description: Bad stuff!
Line number 243, File name: myfile.cpp
Time: 12/31/2013 08:24:20

#continue log
#continue log
#continue log
#continue log

This code will break it down into chunks you can parse easily:

此代码将其分解为可以轻松解析的块:

File.foreach('test.log').slice_before(/^\s*$/).to_a 
# => [["#begin log data above this\n"],
#     ["\n",
#      "Exception: Error code 50100\n",
#      "Description: Bad stuff!\n",
#      "Line number 243, File name: myfile.cpp\n",
#      "Time: 12/31/2013 08:24:20\n"],
#     ["\n",
#      "#continue log\n",
#      "#continue log\n",
#      "#continue log\n",
#      "#continue log\n"],
#     ["\n",
#      "Exception: Error code 50100\n",
#      "Description: Bad stuff!\n",
#      "Line number 243, File name: myfile.cpp\n",
#      "Time: 12/31/2013 08:24:20\n"],
#     ["\n",
#      "#continue log\n",
#      "#continue log\n",
#      "#continue log\n",
#      "#continue log\n"]]

You don't need to_a to loop over it. Do something like:

你不需要to_a来循环它。做类似的事情:

File.foreach('test.log').slice_before(/^\s*$/).each do |chunk|
  # process the chunk
end 

Instead of foreach you can use readlines. The end result should be the same.

而不是foreach,你可以使用readlines。最终结果应该是相同的。