如何在ruby中读/写一个ini文件。我有一个我需要的ini文件
我如何在红宝石中做到这一点?关于这方面的文件很惨淡。
答案 0 :(得分:12)
正如@method所说,使用inifile gem。还有一个ini宝石,但我还没有使用它。
我发现documentation here比宝石页链接到的documentation here更有帮助。
没有太多的例子,所以这里有一些代码可以帮助你入门:
首先,使用以下内容创建文件/tmp/desktop.ini
:
[Desktop Entry]
Version=1.0
Type=Application
Name=Foo Viewer
Comment=The best viewer for Foo objects available!
TryExec=fooview
Exec=fooview %F
Icon=fooview
确保从命令行运行gem install inifile
。
使用以下内容创建/tmp/ini-test.rb
之类的文件:
require 'inifile'
require 'pp'
# read an existing file
file = IniFile.load('/tmp/desktop.ini')
data = file["Desktop Entry"]
#output one property
puts "here is one property:"
puts data["Name"]
# pretty print object
puts "here is the loaded file:"
pp file
# create a new ini file object
new_file = IniFile.new
# set properties
new_file["Desktop Entry"] = {
"Type" => "Application",
"Name" => 'test',
"Exec" => 'command',
}
# pretty print object
puts "here is a object created with new:"
pp new_file
# set file path
new_file.filename = "/tmp/new_ini_file.ini"
# save file
new_file.write()
puts "the new object has been saved as a file to /tmp/new_ini_file.ini"
使用ruby /tmp/ini-test.rb
运行该文件应该会产生类似:
here is one property:
Foo Viewer
here is the loaded file:
{ this output hidden for brevity }
here is a object created with new:
#<IniFile:0x007feeec000770
@comment=";#",
@content=nil,
@default="global",
@encoding=nil,
@escape=true,
@filename=nil,
@ini=
{"Desktop Entry"=>
{"Type"=>"Application",
"Name"=>"test",
"Exec"=>"command",
"Icon"=>"icon_filename",
"Comment"=>"comment"}},
@param="=">
the new object has been saved as a file to /tmp/new_ini_file.ini
根据需要修改以满足您的需求。
答案 1 :(得分:11)
我最近使用过ruby-inifile。与这里简单的片段相比,这可能是过度杀伤......
答案 2 :(得分:2)
这是用于读取和写入.ini文件的模块,尽可能少地更改原始文件(对于读取人和机器的文件):
class IniFileExc < RuntimeError
end
class IniNode
def initialize(name, value=nil)
@line_start = -1;
@line_end = -1;
@level = 0;
@name = name;
@value = value;
@keys = {};
@keylist = [];
@modified = false;
@deleted = false;
end
attr_reader :level,:line_start,:line_end,:name,:value,:keylist,:keys,:modified,:deleted
attr_writer :level,:line_start,:line_end,:name,:value,:keylist,:keys,:modified,:deleted
def to_str
return @name.to_s + ' = ' + @value.to_s;
end
def to_s
return @value.to_s;
end
def to_i
return @value.to_i
end
def to_f
return @value.to_f;
end
def
insert(key, nil);
return @keys[key];
end
def insert(key, value)
return false if (@keys.has_key?(key));
node = nil;
if (value && ((value.class == IniNode) || (value.class == IniSection)))
node = value;
else
if (@level <= 0)
node = IniSection.new(key);
else
node = IniNode.new(key, value)
end
end
node.line_start = @line_end + 1 if (node.line_start < 0);
node.level = @level + 1;
@keys[key] = node;
@keylist.push(key);
return true;
end
def []=(key, value)
rc = insert(key, value);
@keys[key].value = value;
@keys[key].modified = true;
@modified = true;
end
def delete(key)
return false if (! @keys.has_key?(key));
@keys[key].deleted = true;
@modified = true;
end
end
class IniSection < IniNode
def initialize(name)
super(name);
end
def to_str
return ('[' + @name + ']');
end
end
class IniFile < IniNode
def initialize(path, load=true)
super(path);
@lines = [];
reload() if (load);
end
def reload
begin
input = File.new(@name, "r");
rescue
raise;
else
prevnode = node = self;
lineno = 0;
input.each do |line|
@lines.push(line);
parsed_node = parse_line(lineno, line);
if (parsed_node);
if (parsed_node.class == IniSection)
if (parsed_node != node)
prev_node = node;
node = parsed_node;
insert(node.name, node);
prev_node.line_end = lineno - 1;
end
else
node.insert(parsed_node.name, parsed_node);
end
end
lineno += 1;
end
input.close;
node.line_end = @line_end = lineno - 1;
end
end
def parse_line(lineno, line)
return nil if (line =~ /^\s*$/);
return nil if (line =~ /^\s*#/);
return nil if (line =~ /^\s*;/);
if (line =~ /^\s*[\s*(.+)\s*].$/)
rv = IniSection.new($1);
rv.line_start = lineno;
rv.level = @level + 1;
return rv;
elsif (line =~ /^\s(\S?.[^=\s])\s=\s*(\S?[^#;][^#;\s\n]).$/)
rv = IniNode.new($1, $2);
rv.line_start = rv.line_end = lineno;
rv.level = @level + 2;
return rv;
end
return nil;
end
def write
inserted = {};
@keylist.each do |sect|
sectnode = @keys[sect];
next if (!sectnode.modified || sectnode.deleted);
if (sectnode.line_end < 0)
@lines.push("\n");
@lines.push(sectnode.to_str + "\n");
end
sectnode.keylist.each do |key|
keynode = sectnode.keys[key];
next if (!keynode.modified || keynode.deleted);
if (keynode.line_end < 0)
if (sectnode.line_end < 0)
@lines.push(keynode.to_str + "\n");
else
idx = sectnode.line_end.to_i;
inserted[idx] = [] if (! inserted.has_key?(idx));
inserted[idx].push(keynode.to_str);
end
else
line = @lines[keynode.line_start];
if (line =~ /^(\s*)(\S?.[^=\s]\s=\s*\S?.+[^#;\s])(\s*[#;].)$/)
line = $1 + keynode.to_str + $3 + "\n";
else
line = line.gsub(/^(\s)(\S?.[^=\s]\s=\s*\S?[^#;]+[^#;\n\s])(.*)$/){
$1 + keynode.to_str + $3};
end
@lines[keynode.line_start] = line;
end
end
end
node.line_end = @line_end = lineno - 1;
end
用法示例:
deleted = {};
@keylist.each do |sect|
sectnode = @keys[sect];
next if (!sectnode.deleted && !sectnode.modified);
if (sectnode.deleted && (sectnode.line_start >= 0) && (sectnode.line_end >= 0) \
&& (sectnode.line_end >= sectnode.line_start))
for i in sectnode.line_start..sectnode.line_end
deleted[i] = true;
end
end
sectnode.keylist.each do |key|
keynode = sectnode.keys[key];
next if (!keynode.deleted);
deleted[keynode.line_start.to_i] = true \
if ((keynode.line_start >= 0) && (keynode.line_end >= 0) && (keynode.line_start == keynode.line_end));
end
end
begin
file = File.new(@name, 'w');
rescue
raise(IniFileExc, "Failed to open " + @name + " for writing: #{$!}", caller);
else
cnt = -1;
@lines.each do |line|
cnt += 1;
if (inserted.has_key?(cnt))
inserted[cnt].each do |ins|
file.puts(ins + "\n");
end
end
next if (deleted[cnt]);
file.puts(line);
end
file.close;
end
end
end
希望这有帮助。
答案 3 :(得分:1)
这是另一种选择: http://rubygems.org/gems/ini
答案 4 :(得分:0)
如果我理解正确,
outFile = File.new('out.ini', 'w')
File.open('in.ini', 'r') do |inFile|
inFile.each_line do |line|
# foo is the entry you want to change, baz is its new value.
outFile.puts(line.sub(/foo=(.*)/, 'foo=baz'))
end
end
outFile.close
请注意,当您对块使用File.open
时,文件将在块终止时自动关闭。
答案 5 :(得分:-4)
file = File.new("your.ini", "r")
while (line = file.gets)
puts "#{line}" #additionally make changes
end
file.close