2010-11-03 43 views
2

我有一堆管道分隔的文件在生成时没有正确转义回车符,所以我不能使用CR或换行符来分隔行。不过,我知道每个记录都必须有7个字段。每行读入固定数量的管道分隔字段?

Ruby 1.9中的CSV库设置'col_sep'参数很容易将字段拆分,但'row_sep'参数不能设置,因为我在这些字段中有换行符。

有没有办法使用固定数量的字段作为行分隔符来解析管道分隔文件?

谢谢!

+0

你可以给一个分隔字符串的例子。 – Trez 2010-11-03 02:16:54

回答

1

下面是做这件事的一种方法:

构建的七个字样本字符串,在 中间串的嵌入的新行。有三行值得。

text = (["now is the\ntime for all good"] * 3).join(' ').gsub(' ', '|') 
puts text 
# >> now|is|the 
# >> time|for|all|good|now|is|the 
# >> time|for|all|good|now|is|the 
# >> time|for|all|good 

过程是这样的:

lines = [] 
chunks = text.gsub("\n", '|').split('|') 
while (chunks.any?) 
    lines << chunks.slice!(0, 7).join(' ') 
end 

puts lines 
# >> now is the time for all good 
# >> now is the time for all good 
# >> now is the time for all good 

所以,这显示了我们可以重建行。

假装的话实际上是从管道分隔的文件栏,我们可以使代码通过取出.join(' ')做真实的东西:

while (chunks.any?) 
    lines << chunks.slice!(0, 7) 
end 

ap lines 
# >> [ 
# >>  [0] [ 
# >>   [0] "now", 
# >>   [1] "is", 
# >>   [2] "the", 
# >>   [3] "time", 
# >>   [4] "for", 
# >>   [5] "all", 
# >>   [6] "good" 
# >>  ], 
# >>  [1] [ 
# >>   [0] "now", 
# >>   [1] "is", 
# >>   [2] "the", 
# >>   [3] "time", 
# >>   [4] "for", 
# >>   [5] "all", 
# >>   [6] "good" 
# >>  ], 
# >>  [2] [ 
# >>   [0] "now", 
# >>   [1] "is", 
# >>   [2] "the", 
# >>   [3] "time", 
# >>   [4] "for", 
# >>   [5] "all", 
# >>   [6] "good" 
# >>  ] 
# >> ] 
0

这里有一个想法,使用正则表达式:

#!/opt/local/bin/ruby 

fp = File.open("pipe_delim.txt") 
r1 = /.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|/m 
results = fp.gets.scan(r1) 
results.each do |result| 
    puts result 
end 

此正则表达式似乎绊倒在一个领域内换行,但我敢肯定,你可以调整它才能正常工作。

0

只是一个想法,但cucumber测试宝石有Cucumber::Ast::Table您可以用来处理此文件的类。

Cucumber::Ast::Table.new(File.read(file)) 

然后我认为这是rows方法可以用来读出它。

0

尝试使用String#splitEnumerable#each_slice

result = [] 
text.split('|').each_slice(7) { |record| result << record } 
1

例如说你想解析所有慈善机构在IRS txt文件是管道分隔。

假设您有一个名为Charity的模型,它的所有字段都与您的管道分隔文件相同。

class Charity < ActiveRecord::Base 
    # http://apps.irs.gov/app/eos/forwardToPub78DownloadLayout.do 
    # http://apps.irs.gov/app/eos/forwardToPub78Download.do 
    attr_accessible :city, :country, :deductibility_status, :deductibility_status_description, :ein, :legal_name, :state 
end 

你可以叫import.rake

namespace :import do 

    desc "Import Pipe Delimted IRS 5013c Data " 
    task :irs_data => :environment do 

    require 'csv' 

    txt_file_path = 'db/irs_5013cs.txt' 
    results = File.open(txt_file_path).readlines do |line| 
     line = line.split('|').each_slice(7) 
    end 

    # Order Field Notes 
    # 1 EIN Required 
    # 2 Legal Name Optional 
    # 3 City Optional 
    # 4 State Optional 
    # 5 Deductibility Status Optional 
    # 6 Country Optional - If Country is null, then Country is assumed to be United States 
    # 7 Deductibility Status Description Optional 

    results.each do |row| 
     row = row.split('|').each_slice(7).to_a.first 
     #ID,Category,Sub Category,State Standard 
     Charity.create!({ 
     :ein        => row[0], 
     :legal_name      => row[1], 
     :city        => row[2], 
     :state       => row[3], 
     :deductibility_status    => row[4], 
     :country       => row[5], 
     :deductibility_status_description => row[6] 
     }) 
    end 
    end 
end 

rake任务终于可以运行此导入通过键入您的Rails应用程序下面的命令行

rake import:irs_data 
相关问题