我有一个包含大量主机名和选项的长文件。
类似
hostname {
option 1
option 2
option 3
}
该文件大约有2000个主机名。我想在ruby中做的是:
打开文件 开始阅读 当我到主机名创建一个具有该主机名的文件 并且只有当它停止时,才从该主机名中提取相同的信息 并继续下一个主机名/重复
答案 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 {
启动一个新文件,然后在}
关闭它。介于两者之间的所有内容都存储在新文件中。如果目标文件已存在,则脚本将停止并显示异常。