I just wanted this function to run and get the output, but I can't seem to make it run.
I installed Interactive Ruby for this.
This is the code:
class Float
def to_sn # to scientific notation
"%E" % self
end
def self.from_sn str # generate a float from scientific notation
("%f" % str).to_f
end
end
# Pass in filename as only argument
if ARGV.size != 1
puts "Usage: ./converSTL.rb [stl filename]"
exit
end
begin
original = File.new(ARGV[0], "r")
# Read first line - check binary or ASCII
tempLine = original.gets
if tempLine.include? "solid"
outFilename = ARGV[0].sub(/\.stl/i, '-binary.stl')
puts "#{ARGV[0]} is in ASCII format, converting to BINARY: #{outFilename}"
outFile = File.new(outFilename, "w")
outFile.write("\0" * 80) # 80 bit header - ignored
outFile.write("FFFF") # 4 bit integer # of triangles - filled later
triCount = 0
while temp = original.gets
next if temp =~ /^\s*$/ or temp.include? 'endsolid' # ignore whitespace
temp.sub! /facet normal/, ''
normal = temp.split(' ').map{ |num| Float.from_sn num }
triCount += 1
temp = original.gets # 'outer loop'
temp = original.gets
vertexA = temp.sub(/vertex/, '').split(' ').map{ |num| Float.from_sn num }
temp = original.gets
vertexB = temp.sub(/vertex/, '').split(' ').map{ |num| Float.from_sn num }
temp = original.gets
vertexC = temp.sub(/vertex/, '').split(' ').map{ |num| Float.from_sn num }
temp = original.gets # 'endsolid'
temp = original.gets # 'endfacet'
outFile.write(normal.pack("FFF"))
outFile.write(vertexA.pack("FFF"))
outFile.write(vertexB.pack("FFF"))
outFile.write(vertexC.pack("FFF"))
outFile.write("\0\0")
end
outFile.seek(80, IO::SEEK_SET)
outFile.write([ triCount ].pack("V"))
outFile.close
else
outFilename = ARGV[0].sub(/\.stl/i, '-ascii.stl')
puts "#{ARGV[0]} is in BINARY format, converting to ASCII: #{outFilename}"
outFile = File.new(outFilename, "w")
outFile.write("solid \n")
original.seek(80, IO::SEEK_SET)
triCount = original.read(4).unpack('V')[0]
triCount.times do |triNdx|
normal = original.read(12).unpack('FFF')
vertexA = original.read(12).unpack('FFF')
vertexB = original.read(12).unpack('FFF')
vertexC = original.read(12).unpack('FFF')
original.seek(2, IO::SEEK_CUR)
outFile.write(" facet normal #{normal[0].to_sn} #{normal[1].to_sn} #{normal[2].to_sn}\n")
outFile.write(" outer loop\n")
outFile.write(" vertex #{vertexA[0].to_sn} #{vertexA[1].to_sn} #{vertexA[2].to_sn}\n")
outFile.write(" vertex #{vertexB[0].to_sn} #{vertexB[1].to_sn} #{vertexB[2].to_sn}\n")
outFile.write(" vertex #{vertexC[0].to_sn} #{vertexC[1].to_sn} #{vertexC[2].to_sn}\n")
outFile.write(" endloop\n")
outFile.write(" endfacet\n")
end
outFile.write("endsolid \n")
outFile.close
end
original.close
rescue => error
puts "Error: #{error}"
end
And everytime I try to run it, I get this error:
It's a script that can be run from cmd with
ruby convertST1.rb file.stl
Related
I have wrote my ruby script for that. In that you can check "all_data" has all required content.
#!/usr/bin/env ruby
require 'docx'
file_data = []
name_file = "test"
t = ""
array_desc = []
heading_hash = {}
all_data = {}
temp = ""
output = ""
folder_name = ""
directory_name = ""
flag = true
count = 0
md_file_name = ''
Dir.glob("**/*.docx") do |file_name|
doc = Docx::Document.open(file_name)
first_table = doc.tables[0]
doc.tables.each do |table|
table.rows.each do |row| # Row-based iteration
row.cells.each_with_index do |cell, i|
if i == 2
file_data << cell.text.gsub('=','')
end
end
end
end
file_data.each_with_index do |l, d|
if l.include? file_data[d]
if ((l.strip)[0].to_i != 0)
md_file_name = file_data[d].split(".")
#start folder name
if flag
directory_name = md_file_name[0].to_i
flag = false
end
count +=1
t = file_data[d+1]
if(array_desc.size > 0)
heading_hash[temp] = array_desc
all_data[md_file_name[0].strip] = heading_hash
array_desc = []
end
else
if(t != l)
array_desc << l
temp = t
end
end
end
end
if(array_desc.size> 0)
heading_hash[temp] = array_desc
all_data[md_file_name[0].strip] = heading_hash
array_desc = []
end
all_data.each do |k, v|
v.each do |(hk, hv)|
if hk != ""
chapter_no = k
if (k[0,1] == 0.to_s)
chapter_no = k
else
chapter_no = "0#{k}"
end
Dir.mkdir("#{chapter_no}") unless File.exists?("#{chapter_no}")
output_name = "#{chapter_no}/#{File.basename("01", '.*')}.md"
output = File.open(output_name, 'w')
# output << "#"+"#{hk}\n\n"
# output << "#{hv} \n\n"
hv.each do |des|
# puts des
end
end
end
end
end
source docx file
download above file and put sctip and docx (source file) in same folder. When you will run script form terminal ($./script.rb) you will see folder name as 01,02.....etc. And inside there will be file with md extension.
I want to output as below description:
## FOLDER 01 > FILE 01.md, here data in file like hk as heading (for Heading you can put # before hk)and hv
## FOLDER 02 > FILE 01.md, here data in file like hk as heading (for Heading you can put # before hk)and hv
Please use my code and check that is working or not.
Dir.glob("**/*.docx") do |file_name|
doc = Docx::Document.open(file_name)
first_table = doc.tables[0]
doc.tables.each do |table|
table.rows.each do |row|
row.cells.each_with_index do |cell, i|
if i == 2
file_data << cell.text.gsub('=','')
end
end
end
end
file_data.each_with_index do |l, d|
if ((l.strip)[0].to_i != 0)
md_file_name = file_data[d].split(".")
#start folder name
if flag
directory_name = md_file_name[0].to_i
flag = false
end
count +=1
t = file_data[d+1]
if(array_desc.size > 0)
heading_hash[temp] = array_desc
array_desc=[]
all_data[file_data[d+1]] = array_desc
end
else
if(t != l)
array_desc << l
temp = t
end
end
end
chapter_no = 1
all_data.each do |k, v|
Dir.mkdir("#{chapter_no}") unless File.exists?("#{chapter_no}")
output_name = "#{chapter_no}/#{File.basename("01", '.*')}.md"
output = File.open(output_name, 'a')
output << "#"+"#{k}\n\n"
v.each do |d|
output << "#{d} \n"
end
chapter_no= chapter_no+1
end
end
It will give exact output as you shared above. Let me know if you need more help.
Im trying to wrapped this two command in ruby but not work
ruby -a -ne 'print $F[0].gsub(/=(.*?)&/," \"\\1\" and ")' prueban > prueban2
ruby -a -F';' -ne 'puts $F[0].sub("less"," <")' prueban2 > prueban3
this is my command
File.open("text.txt", "r") do |fi|
fi.readlines.each do |line|
parts = line.chomp.split(';')
fx= puts parts[0].gsub(/=(.*?)&/," \"\\1\" and ")
end
fx.readlines.each do |line|
parts = line.chomp.split(';')
fx= puts parts[0].gsub("less"," <")
end
end
this is my file
pricegreater=2&priceless=4&seleccionequal=pet&
and this is my expected output
pricegreater "2" and price < "4" and seleccionequal "pet" and
I dont know whats is doing wrong please help me
Here's a reworked version of the core function to show how to do it in a more Ruby-esque way:
# Define a lookup table of all substitutions
REWRITE = {
'greater' => '>',
'less' => '<',
'equal' => '='
}
# Use the lookup table to create a regular expression that matches them all
REWRITE_RX = Regexp.new(Regexp.union(REWRITE.keys).to_s + '\z')
def rewrite(input)
# Split up each main part of the input on &
input.split('&').map do |pair|
# Carve up each part into a var and value on =
var, value = pair.split('=')
# Replace terms found in the lookup table
var.sub!(REWRITE_RX) do |m|
' ' + REWRITE[m]
end
# Combine these to get the result
[ var, value ].join(' ')
end.join(' and ')
end
Put into action you get this:
rewrite("pricegreater=2&priceless=4&seleccionequal=pet&")
# => "price > 2 and price < 4 and seleccion = pet"
I solved with this
File.open("text.txt", "r") do |fi|
fi.readlines.each do |line|
parts = line.chomp.split(';')
f = File.open('text2.txt', 'w')
old_out = $stdout
$stdout = f
puts parts[0].gsub(/=(.*?)&/," \"\\1\" and ")
f.close
$stdout = old_out
end
end
File.open("text2.txt", "r") do |fi|
fi.readlines.each do |line|
parts = line.chomp.split(';')
f = File.open('text3.txt', 'w')
old_out = $stdout
$stdout = f
puts parts[0].sub("less"," <")
f.close
$stdout = old_out
end
end
I'm not a programmer, but I want to become one. So, I read books, I do tutorials and I ask questions. Here is the question:
I'm trying to do a Ruby quiz – the one with the Solitaire cypher (http://rubyquiz.com/quiz1.html). I wrote some code that works pretty well, except that at one point it alters the key_deck array which should be a reference to the end of the program. I do not know where this happens or why.
Here is my noobish code:
$characters = Array ('A' .. 'Z')
def encode to_encode, input_deck
trekljdfg = input_deck
edeck = input_deck
work_string = ''
to_encode.upcase.split("").each do |char|
if $characters.include?(char)
work_string.concat(char)
end
end
work_string = work_string + ('X' * ((5 - (work_string.length % 5)) % 5))
keystream_string = ''
while keystream_string.length < work_string.length do # <-- generate keystream
edeck = permutation(edeck)
keystream_string.concat(get_letter(edeck))
end
encoded = combine_with_keystream(work_string, keystream_string)
encoded = split_string_in_groups(encoded)
return encoded
end
def decode to_decode, input_deck
ddeck = input_deck
to_decode = to_decode.delete(' ')
keystream_string = ''
while keystream_string.length < to_decode.length do # <-- generate keystream
ddeck = permutation(ddeck)
keystream_string.concat(get_letter(ddeck))
end
array_to_decode = text_to_numbers to_decode
array_keystream_string = text_to_numbers keystream_string
decoded = ''
for i in 0..(array_to_decode.length-1)
if array_to_decode[i] >= array_keystream_string[i]
decoded.concat($characters[(array_to_decode[i] - array_keystream_string[i])-1])
else
decoded.concat($characters[(array_to_decode[i] + 26 - array_keystream_string[i])-1])
end
end
decoded = split_string_in_groups decoded
return decoded
end
def permutation deck_to_change
deck = deck_to_change
def swap array, joker
work_array = array
joker_position = work_array.index(joker)
if joker_position == (work_array.length-1)
temp_array = work_array.slice!(1..(work_array.length-2))
work_array = work_array + temp_array
else
work_array[joker_position], work_array[joker_position+1] = work_array[joker_position+1], work_array[joker_position]
end
return work_array
end
deck = swap(deck, 'A') # <-- swap first joker
2.times do # <-- swap second joker
deck = swap(deck, 'B')
end
if deck.index('A') < deck.index('B') # <-- triple cut
joker_position1 = deck.index('A')
joker_position2 = deck.index('B') - joker_position1
else
joker_position1 = deck.index('B')
joker_position2 = deck.index('A') - joker_position1
end
if joker_position1 == 0
temp_array1 = []
else
temp_array1 = deck.slice!(0..joker_position1-1)
end
if joker_position2 == deck.length-1
temp_array2 = []
else
temp_array2 = deck.slice!(joker_position2+1..deck.length-1)
end
deck = temp_array2 + deck + temp_array1
if (deck.last != 'A') | (deck.last != 'B') # <-- count cut
temp_array1 = deck.slice!(0..deck.last.to_i-1)
temp_array2 = deck.pop(1)
deck = deck + temp_array1 + temp_array2
end
return deck
end
def get_letter deck
first = deck.first
case first
when 'A'
first = '53'
when 'B'
first = '53'
end
if (deck[first.to_i] == 'A') | (deck[first.to_i] == 'B')
return ''
else
return $characters[((deck[first.to_i]).to_i-1) % 26]
end
end
def text_to_numbers text
array = []
text.upcase.split("").each do |char|
array.push($characters.index(char)+1)
end
return array
end
def combine_with_keystream string1, string2
temp_array1 = text_to_numbers string1
temp_array2 = text_to_numbers string2
string = ''
for i in 0..(temp_array1.length-1)
tmp = temp_array1[i] + temp_array2[i]
if tmp > 26
tmp = tmp - 26
end
string.concat($characters[tmp-1])
end
return string
end
def split_string_in_groups string
return string.scan(/.{1,5}/).join(" ")
end
#-begin-------------------------
key_deck = ('1' .. '52').to_a + ['A', 'B'] # <-- this is the key deck ^^
string_to_encode = 'Code in Ruby live longer!' # <-- this is the string to be encoded
string_to_decode = 'GLNCQ MJAFF FVOMB JIYCB' # <-- this is the string to be decoded
puts "Your encoded text is: #{encode(string_to_encode, key_deck)}"
puts "Your decoded text is: #{decode(string_to_decode, key_deck)}"
You are using slice! to find your deck's permutations, which changes the input array.
The easiest solution is to dup the array before working on it:
def encode to_encode, input_deck
trekljdfg = input_deck.dup
edeck = input_deck.dup
# ..
end
def decode to_decode, input_deck
ddeck = input_deck.dup
# ..
end
dup creates a copy of the array, which you can safely mutilate.
Your permutation function alters the deck. You pass it a reference to the original deck, so any changes you do on the reference will actually change the original. Try something like this instead:
key_deck = [....]
...
puts "#{encode(string_to_encode, key_dec.clone}"
The clone method will make a new copy of the array for you so all changes will only apply to the copy.
Or you can just avoit the entire problem by using the Array#shuffle method:
puts "#{encode(string_to_encode, key_dec.shuffle}"
That will give an already shuffled deck to the encode function.
I am quit new in ruby and I need your help.
Now I want to write ruby code to collect some data while looping.
I have 2 code for this work.
My objective is collect sum score from text that split from input file.
-first, run test_dialog.rb
-Second, change input file for this format
from
AA:0.88:320:800|BB:0.82:1040:1330|CC:0.77:1330:1700 enquire-privilege_card
to
AA 0.88
BB 0.82
CC 0.77
-Then use each text that separate check on dialog condition. If this data appear in dialog ,store point until end of text (AA --> BB --> CC)
-Finally get average score.
I have problem will separating and use loop for collect point in same time.
Please help.
Best regard.
PS.
score will return if match with dialog
score of input line 1 should be (0.88+0.82+0.77/3) [match condition 1].
if no match, no score return.
Input data
AA:0.88:320:800|BB:0.82:1040:1330|CC:0.77:1330:1700 enquire-privilege_card
BB:0.88:320:800|EE:0.82:1040:1330|FF:0.77:1330:1700 enquire-privilege_card
EE:0.88:320:800|QQ:0.82:1040:1330|AA:0.77:1330:1700|RR:0.77:1330:1700|TT:0.77:1330:1700 enquire-privilege_card
test_dialog.rb
#!/usr/bin/env ruby
# encoding: UTF-8
#
# Input file:
# hyp(with confidence score), ref_tag
#
# Output:
# hyp, ref_tag, hyp_tag, result
#
require_relative 'dialog'
require_relative 'version'
unless ARGV.length > 0
puts 'Usage: ruby test_dialog.rb FILENAME [FILENAME2...]'
exit(1)
end
counter = Hash.new{|h,k| h[k]=Hash.new{|h2,k2| h2[k2]=Hash.new{|h3,k3| h3[k3]=0}}}
thresholds = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
puts %w(hyp ref_tag hyp_tag result).join("\t")
ARGV.each do |fname|
open(fname, 'r:UTF-8').each do |line|
hyp, ref_tag = line.strip.split(/\t/)
key = if ref_tag == "(reject)"
:reject
else
:accept
end
counter[fname][key][:all] += 1
thresholds.each do |threshold|
hyp_all = get_response_text(hyp, threshold)
hyp_tag = if hyp_all==:reject
"(reject)"
else
hyp_all.split(/,/)[1]
end
result = ref_tag==hyp_tag
counter[fname][key][threshold] += 1 if result
puts [hyp.split('|').map{|t| t.split(':')[0]}.join(' '),
ref_tag, hyp_tag, result].join("\t") if threshold==0.0
end
end
end
STDERR.puts ["Filename", "Result"].concat(thresholds).join("\t")
counter.each do |fname, c|
ca_all = c[:accept].delete(:all)
cr_all = c[:reject].delete(:all)
ca = thresholds.map{|t| c[:accept][t]}.map{|n| ca_all==0 ? "N/A" : '%4.1f' % (n.to_f/ca_all*100) }
cr = thresholds.map{|t| c[:reject][t]}.map{|n| cr_all==0 ? "N/A" : '%4.1f' % (n.to_f/cr_all*100) }
STDERR.puts [fname, "Correct Accept"].concat(ca).join("\t")
STDERR.puts [fname, "Correct Reject"].concat(cr).join("\t")
end
dialog.rb
# -*- coding: utf-8 -*-
#
# text : AA:0.88:320:800|BB:0.82:1040:1330|CC:0.77:1330:1700|DD:0.71:1700:2010|EE:1.00:2070:2390|FF:0.56:320:800|GG:0.12:1330:1700
#
def get_response_text text, threshold, dsr_session_id=nil
# ...
#p "result text >> " + text
# Promotion => detail => rate
# Promotion IR/IDD => high priority than enquire-promotion
# Rate IR/IDD => high priority than enquire-rate
# Problem IR/IDD => high priority than enquire-service_problem
# Internet IR/IDD => high priority than enquire-internet
# Cancel Net => enquire-internet NOT cancel-service
# Lost-Stolen => +Broken
memu = ""
intent = ""
prompt = ""
intent_th = ""
intent_id = ""
# strInput = text.gsub(/\s/,'')
strInput = text.split('|').map{|t| t.split(':')[0]}.join('')
puts ("****strINPUT*****")
puts strInput
scores = text.split('|').map{|t| t.split(':')[1].to_f}
puts ("****SCORE*****")
puts scores
avg_score = scores.inject(0){|a,x| a+=x} / scores.size
puts ("****AVG-Score*****")
puts avg_score
if avg_score < threshold
return :reject
end
# List of Country
country_fname = File.dirname(__FILE__)+"/country_list.txt"
country_list = open(country_fname, "r:UTF-8").readlines.map{|line| line.chomp}
contry_reg = Regexp.union(country_list)
# List of Mobile Type
mobile_fname = File.dirname(__FILE__)+"/mobile_list.txt"
mobile_list = open(mobile_fname, "r:UTF-8").readlines.map{|line| line.chomp}
mobile_reg = Regexp.union(mobile_list)
# List of Carrier
carrier_fname = File.dirname(__FILE__)+"/carrier_list.txt"
carrier_list = open(carrier_fname, "r:UTF-8").readlines.map{|line| line.chomp}
carrier_reg = Regexp.union(carrier_list)
if (strInput =~ /AA|BB/ and strInput =~ /CC/)
intent = "enquire-payment_method"
elsif (strInput =~ /EE/) and ("#{$'}" =~ /QQ|RR/)
intent = "enquire-balance_amount"
elsif (strInput =~ /AA|EE/i) and (strInput =~ /TT/i)
intent = "enquire-balance_unit"
elsif (strInput =~ /DD|BB|/i) and (strInput =~ /FF|AA/i)
intent = "service-balance_amount"
end
Parse as follows:
str = 'AA:0.88:320:800|BB:0.82:1040:1330|CC:0.77:1330:1700 enquire-privilege_card'
str.split( /[:|]/ ).select.with_index {| code, i | i % 4 < 2 ; }.join( ' ' )
# => "AA 0.88 BB 0.82 CC 0.77"
How do I read/write an ini file in ruby. I have an ini file that I need to
read
change an entry
write out to a different location
How would I do that in ruby? The documentation on this is bleak.
Use the InIFile Gem
As #method said, use the inifile gem. There is also an ini gem but I haven't used it.
I found the documentation here a slightly more helpful than the documentation here which is where the gem page links to.
There were not many examples so here is a bit of code to get you started:
Example Setup
First, create a file /tmp/desktop.ini with these contents:
[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
Make sure you have run gem install inifile from the command line.
Example Code
Create a file like /tmp/ini-test.rb with these contents:
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"
Example Results
Running that file with ruby /tmp/ini-test.rb should yield something like:
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
Modify as required suit your needs.
I recently used ruby-inifile. Maybe it's overkill compared to the simple snippets here...
Here's the module for reading and writing of .ini-files with as less change to original file as possible (for files which read humans and machines):
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
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
Usage example:
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
Hope this helps.
Here's another option:
http://rubygems.org/gems/ini
If I understand correctly,
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
Note that when you use File.open with a block, the file will automatically be closed when the block terminates.
file = File.new("your.ini", "r")
while (line = file.gets)
puts "#{line}" #additionally make changes
end
file.close