我有一堆管道分隔的文件在生成时没有正确转义回车符,所以我不能使用CR或换行符来分隔行。不过,我知道每个记录都必须有7个字段。每行读入固定数量的管道分隔字段?
Ruby 1.9中的CSV库设置'col_sep'参数很容易将字段拆分,但'row_sep'参数不能设置,因为我在这些字段中有换行符。
有没有办法使用固定数量的字段作为行分隔符来解析管道分隔文件?
谢谢!
我有一堆管道分隔的文件在生成时没有正确转义回车符,所以我不能使用CR或换行符来分隔行。不过,我知道每个记录都必须有7个字段。每行读入固定数量的管道分隔字段?
Ruby 1.9中的CSV库设置'col_sep'参数很容易将字段拆分,但'row_sep'参数不能设置,因为我在这些字段中有换行符。
有没有办法使用固定数量的字段作为行分隔符来解析管道分隔文件?
谢谢!
下面是做这件事的一种方法:
构建的七个字样本字符串,在 中间串的嵌入的新行。有三行值得。
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"
# >> ]
# >> ]
这里有一个想法,使用正则表达式:
#!/opt/local/bin/ruby
fp = File.open("pipe_delim.txt")
r1 = /.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|.*?\|/m
results = fp.gets.scan(r1)
results.each do |result|
puts result
end
此正则表达式似乎绊倒在一个领域内换行,但我敢肯定,你可以调整它才能正常工作。
只是一个想法,但cucumber
测试宝石有Cucumber::Ast::Table
您可以用来处理此文件的类。
Cucumber::Ast::Table.new(File.read(file))
然后我认为这是rows
方法可以用来读出它。
尝试使用String#split
和Enumerable#each_slice
:
result = []
text.split('|').each_slice(7) { |record| result << record }
例如说你想解析所有慈善机构在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
你可以给一个分隔字符串的例子。 – Trez 2010-11-03 02:16:54