7


4

iniファイルをrubyで読み書きするにはどうすればいいですか。 必要なiniファイルがあります。

  1. 読む

  2. エントリを変更する

  3. 別の場所に書き出す

どうやってルビーでやるの? これに関するドキュメントは暗いです。

6 Answer


12


InIFile Gemを使う

@methodが言ったように、http://rubygems.org/gems/inifile[inifile] gemを使ってください。 ini gemもありますが、私は使っていません。

私はhttp://www.ruby-doc.org/gems/docs/i/inifile-2.0.1/IniFile.html[documentation]がhttp://rubydoc.info/gems/よりも少し役に立つことを発見しました。 ini / 0.1.1 / frames [ドキュメントはこちら]ここからgemページへのリンク先です。

例はそれほど多くありませんでしたので、ここから始めましょう。

設定例

まず、以下の内容のファイル `/ 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:
#
    {"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

必要に応じて変更してください。


11


私は最近 ruby-inifileを使いました。 多分それはここの簡単な抜粋と比較してやり過ぎです…​


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)は、(line =〜/ ^ \ s * $ /);の場合、nilを返します。 (line =〜/ ^ \ s #/);の場合はnilを返します。 (line =〜/ ^ \ s *; /);の場合はnilを返します。 if(行=〜/ ^ \ s * [\ s *(。)\ s *] ._ $ /)rv = IniSection.new($ 1); rv.line_start = lineno; rv.level = @level 1; 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; rvを返します。終了リターンnil。終わり

挿入されたデフ書き込み= \ {}; @ keylist.each do | sect | sectnode = @keys [sect];次にif(!sectnode.modified || sectnode.deleted); if(sectnode.line_end <0)@ lines.push( "\ n"); @ lines.push(sectnode.to_str "\ n");終了sectnode.keylist.each do | key | keynode = sectnode.keys [key];次にif(!keynode.modified || keynode.deleted); if(keynode.line_end <0)if(sectnode.line_end <0)@ lines.push(keynode.to_str "\ n");そうでなければidx = sectnode.line_end.to_i;挿入された[idx] = [] if(! 挿入された.has_key?(idx)); [idx] .push(keynode.to_str)を挿入しました。それ以外の場合はline = @lines [keynode.line_start]; if(line =〜/(\s*)(\S?.[=\s]\s=\s*\S ?. [^#; \ s])(\ s * [#;] ._)$ /)line = $ 1 keynode.to_str $ 3 "\ n";それ以外の場合はline = line.gsub(/ ^(\ s _)(\ S?. [^ = \ s] \ s = \ s * \ S?[^#;] [^#; \ n \ s])( 。*)$ /)\ {$ 1 keynode.to_str $ 3}; end @lines [keynode.line_start] = line;終了終了終了

``

    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

終末

使用例

begin
  ini = IniFile.new('file.ini');
  ini['common']['param'] = 'value';
  ini['common'].delete('unused_param');
  ini.delete('unused_section');
  print "Valuable value: ", ini['common']['param'], "\n";
  ini.write;
rescue IniFileExc
  print "Oh, that's not good: ", $!, "\n";
end

お役に立てれば。


1


これは別の選択肢です:http://rubygems.org/gems/ini


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`を使うと、ブロックが終了するとファイルは自動的に閉じられます。


-4


file = File.new( "your.ini"、 "r")の間(line = file.gets)は "#{line}"を追加します。#最後に変更を加えますfile.close