在ruby中拆分文本文件

我有一个包含几个不同部分的文本文件。 每个部分都有一个标题,后跟实际数据。 例如:

Header1 x,y,z x,y,z x,y,z Header2 a,b,c a,b,c a,b,c 

我希望一次性读取文件并对每个部分下的数据执行不同的操作。 我知道如何解析数据,但是我无法弄清楚如何编写逻辑“执行此操作直到达到Header2,然后执行其他操作,直到Header3等”。

我正在使用ruby,我没有真正遇到任何这样做的例子。 有什么建议?

最简单的你可以这样做:

 # Process lines for header1 def do_header1(line) puts line.split(/,/).join("|") end # Process lines for header2 def do_header2(line) puts line.split(/,/).map{ |e| e.upcase}.join(",") end header1 = false header2 = false # Main loop File.open("file.txt").each_line do |line| if line.chomp == 'Header1' # or whatever match for header1 header1 = true header2 = false next end if line.chomp == 'Header2' # or whatever match for header2 header1 = false header2 = true next end do_header1(line) && next if header1 do_header2(line) && next if header2 end 

如果标头数量过高,您可以使用整数开始跟踪标头:

 header = -1 # Main loop File.open("file.txt").each_line do |line| if line.chomp == 'Header1' # or whatever match for header1 header = 1 next end if line.chomp == 'Header2' # or whatever match for header2 header = 2 next end do_header1(line) && next if header == 1 do_header2(line) && next if header == 2 end 

使用对象的解决方案。 对于每一行,您会询问每个解析器是否已启动解析器可以解析的新节。

 class Section1Parser def section? potential_header potential_header.chomp == 'Header1' end def parse line puts "Section 1: #{line.split(/,/).join("|")}" end end class Section2Parser def section? potential_header potential_header.chomp == 'Header2' end def parse line puts "Section 2: #{line.split(/,/).join("|")}" end end parsers = [Section1Parser.new, Section2Parser.new] selected_parser = nil File.open("c:\\temp\\file.txt").each_line do |line| if new_parser_detected = parsers.detect {|p| p.section? line } selected_parser = new_parser_detected next # skip header end selected_parser.parse line if selected_parser end 

这样的东西会起作用吗?

 File.open('datafile').each_line do |s| if s =~ /^headerpattern$/ #Start a new parsing block ... else #Parse data ... end end 

在我的情况下,’Header’采用以下字符串OBJECT ObjectType ObjectNumber ObjectName

 if File.exist?("all.txt") then object_file = File File.open("all.txt").each_line do |line| file_name = case when line.match('^OBJECT Table.*') "TAB" + line.split[2] + ".TXT" when line.match('^OBJECT Form.*') "FOR" + line.split[2] + ".TXT" when line.match('^OBJECT Report.*') "REP" + line.split[2] + ".TXT" when line.match('^OBJECT Dataport.*') "DAT" + line.split[2] + ".TXT" when line.match('^OBJECT XMLPort.*') "XML" + line.split[2] + ".TXT" when line.match('^OBJECT Codeunit.*') "COD" + line.split[2] + ".TXT" when line.match("^OBJECT MenuSuite.*") "MEN" + line.split[2] + ".TXT" when line.match('^OBJECT Page.*') "PAG" + line.split[2] + ".TXT" when line.match('^OBJECT Query.*') "QUE" + line.split[2] + ".TXT" end unless file_name.nil? File.exist?(file_name) { File.delete(file_name) } object_file = File.open(file_name,"w") end object_file.write(line) end end 

但有一些先决条件:我总是确定该文件的第一行将包含一个标题。 我也没有关闭档案(这肯定会把我的业力吸引到零天)。