Ruby CSV解析、换行符/换行符问题

Ruby CSV解析、换行符/换行符问题,ruby,excel,csv,Ruby,Excel,Csv,我正在尝试为多个CSV文件创建一个解析器,它最终将以Excel兼容的格式输出到另一个CSV文件。CSV文件由采用防火墙配置的商业工具导出,并向我们报告发现的任何问题 到目前为止,我已经知道如何读取中的文件目录,查找某些值,确定我拥有的设备类型,然后将其输出到屏幕或CSV,但前提是每行都有单个单元格条目。如果源IP“单元”(或任何其他单元)包含多个IP,并由换行符分隔,则输出将在该换行符上中断,并将其余IP推到下一行 到目前为止,我掌握的代码是: require 'csv' require 'pp

我正在尝试为多个CSV文件创建一个解析器,它最终将以Excel兼容的格式输出到另一个CSV文件。CSV文件由采用防火墙配置的商业工具导出,并向我们报告发现的任何问题

到目前为止,我已经知道如何读取中的文件目录,查找某些值,确定我拥有的设备类型,然后将其输出到屏幕或CSV,但前提是每行都有单个单元格条目。如果源IP“单元”(或任何其他单元)包含多个IP,并由换行符分隔,则输出将在该换行符上中断,并将其余IP推到下一行

到目前为止,我掌握的代码是:

require 'csv'
require 'pp'

nipperfiles = Dir.glob(ARGV[0] + '/*.csv')

def allcsv(nipperfiles)
  filearray = []
  nipperfiles.each do |csv|
    filearray << csv
  end

  filearray
end

def devicetype(filelist)
  filelist.each do |f|
    CSV.foreach(f, :headers => true, :force_quotes => true) do |row|
      if row["Table"] =~ /audit device list/ && row["Device"] =~ /Cisco/
        return "Cisco"
      elsif row["Table"] =~ /audit device list/ && row["Device"] =~ /Dell/
        return "Sonicwall"
      elsif row["Table"] =~ /audit device list/ && row["Device"] =~ /Juniper/
        return "Juniper"
      end
    end
  end
end

def adminservices(device, filelist)
  administrative = []

  filelist.each do |f|
    CSV.foreach(f, :headers => true, :col_sep => ",", :force_quotes => true, :encoding => Encoding::UTF_8) do |row|
      if row["Table"] =~ /administrative service rule/
        if row["Dst Port"] != "Any" and row["Service"] != "[Host] Any"
          if device == "Cisco"
            administrative << row["Table"] + ',' + row["Rule"] + ',' + row["Protocol"] + ',' + row["Source"] + ',' + row["Destination"] + ',' + row["Dst Port"]
          elsif device == "Sonicwall"
            administrative << row["Table"] + ',' + row["Rule"] + ',' + row["Source"] + ',' + row["Destination"] + ',' + row["Service"]
          elsif device == "Juniper"            
            administrative << row["Table"] + ',' + row["Rule"] + ',' + row["Source"] + ',' + row["Destination"] + ',' + row["Service"]
          end
        end
      end
    end
  end
  administrative
end

def writecsv(admin)

  finalcsv = File.new("randomstorm.csv", "w+")
  finalcsv.puts("Administrative Services Table:\n", admin, "\r\n")
  finalcsv.close

end

filelist = allcsv(nipperfiles)
device = devicetype(filelist)
adminservices(device, filelist)
admin = adminservices(device, filelist)
writecsv(admin)
需要“csv”
需要“pp”
nipperfiles=Dir.glob(ARGV[0]+'/*.csv')
def所有CSV(钳式文件)
filearray=[]
nipperfiles.each do | csv|
filearray true,:force_quotes=>true)do |行|
如果行[“表”]=~/audit device list/&&row[“device”]=~/Cisco/
返回“Cisco”
elsif行[“表”]=~/审核设备列表/&&row[“设备”]=~/Dell/
返回“Sonicwall”
elsif行[“表”]=~/audit device list/&&row[“device”]=~/Juniper/
返回“Juniper”
结束
结束
结束
结束
def adminservices(设备、文件列表)
行政=[]
filelist.each do | f|
foreach(f,:headers=>true,:col_sep=>“,”,:force_quotes=>true,:encoding=>encoding::UTF_8)do |行|
如果行[“表”]=~/管理服务规则/
如果行[“Dst端口”]!=“任意”和行[“服务”]!=“[主机]任何”
如果设备==“Cisco”

管理新行在字段中是可以的,只要它们被引用:

CSV.parse("1,\"2\n\n\",3")
=> [["1", "2\n\n", "3"]]
def writecsv(admin)
 csv_string = CSV.generate do |csv|
   admin.each { |row| csv << row }
 end 

 finalcsv = File.new("randomstorm.csv", "w+")
 finalcsv.puts("Administrative Services Table:\n", csv_string, "\r\n")
 finalcsv.close
end
尝试直接写入字符串或类似中的文件,以确保带换行符的字段被引用:

CSV.parse("1,\"2\n\n\",3")
=> [["1", "2\n\n", "3"]]
def writecsv(admin)
 csv_string = CSV.generate do |csv|
   admin.each { |row| csv << row }
 end 

 finalcsv = File.new("randomstorm.csv", "w+")
 finalcsv.puts("Administrative Services Table:\n", csv_string, "\r\n")
 finalcsv.close
end

分享输入文件Welcome中几个有问题的行的示例。请不要使用告别语(“非常感谢”)或签名(“富有”)。我们在写参考书,而不是讨论,所以你在写一篇文章的第一部分,关于如何解决你所问的问题。另外,您的代码是否是演示问题所必需的最低限度的代码?请阅读“”和“”。请提供与代码一起使用的最小输入数据,并演示问题。期望我们想象这些数据不起作用。广泛使用CSV类。CSV不是一种很好的格式,而且这个类已经过很好的测试,所以它可以处理你从未遇到或想象过的情况。Martin,非常感谢你的回复!这绝对是完美的。我已经用头撞这堵砖墙好几天了。您保存了我的理智。使用
文件的块形式是惯用的Ruby。打开
而不是使用
文件。新建