Ruby,需要读取文件的内容并将其拆分为较小的新文件

时间:2011-09-27 16:57:23

标签: ruby linux

我有一个包含大量主机名和选项的长文件。

类似

hostname {
   option 1
   option 2
   option 3
}

该文件大约有2000个主机名。我想在ruby中做的是:

打开文件 开始阅读 当我到主机名创建一个具有该主机名的文件 并且只有当它停止时,才从该主机名中提取相同的信息 并继续下一个主机名/重复

3 个答案:

答案 0 :(得分:1)

使这项工作的一种方法是,如果您知道{或}不在选项中,则可以在regexp上使用multiline模式的扫描方法:

b.scan( /([^\{]*)(\{)([^\}]*\n)*(\})/m)
=> [["a ", "{", "\n b\n c \n d\n", "}"], 
    ["\nB ", "{", "\n 1\n 2\n 3\n", "}"]]

你需要做一些调整但是它会工作,如果你想把它全部放在内存中用于解析。写入文件应该很简单。

答案 1 :(得分:0)

对于你发布的内容,我想这样的事情可以做到:

str = <<EOF
hostname1 {
  hi
}
hostname2 {
  how
}
hostname3 {
  are
}
EOF

hostnames = str.scan(/^\w+ {.*?}/m)
hostnames.each do |hostname|
    #here save it to a new file
    puts hostname
end

修改
这是一个完整的示例,它将显示hostnames.cfg并将单个文件保存在名为hostnames

的文件夹中

<强> hostnames.cfg

hostname1 {
  hi
}
hostname2 {
  how
}
hostname3 {
  are
}

<强> whatever.rb

file = File.open('./hostnames.cfg', 'r')
content = file.readlines.join
file.close

hostnames = content.scan(/^\w+ {.*?}/m)
hostnames.each do |hostname|
    name = hostname.scan(/^\w+/m).first
    new = File.open("./hostnames/#{name}.cfg", "w+")
    new.write(hostname)
    new.close
end

答案 2 :(得分:0)

我的解决方案:

actual_host = nil
#~ inputfile = File.open(filename)
inputfile = DATA #Only thi stestcase

inputfile.each_line{|line|
  case line
    when /\A\s*(\S+)\s*\{/
      filename = "#{$1}.txt" #write to <<hostname>>.txt
      raise "File already exist" if File.exist?(filename)
      actual_host = File.new(filename, 'w')
    when /\A\s*\}/
      actual_host = nil
    else  #copy data, if inside a host file
      actual_host << line if actual_host
      #Alternative without leading/trailing spaces
      #~ actual_host << line.strip if actual_host
    end
}

inputfile.close

__END__
hostname {
   option 1
   option 2
   option 3
}

它逐行解析并为每个hostname {启动一个新文件,然后在}关闭它。介于两者之间的所有内容都存储在新文件中。如果目标文件已存在,则脚本将停止并显示异常。