I'm trying to scan a large hard drive (think 17TBs) to find a storage estimate for video files within specific folders. In addition, I am trying to find specific unique properties of the video files. The purpose of this is to make a case for a digital asset management system that can support the video files that we have going back to 2009. I'm using mediainfo to inspect each video.
I have the file size/storage count working, but i'm having trouble adding the hashes of video properties to an array in my loop. My goal is for media info to look at the specific properties of each video, put them into a hash and add that hash to an array. Then, once I have collected all the hashes of video properties, I would call uniq! on the array so that it would show me the unique video properties.
The output of my code currently returns the video properties for the last video over and over again. I can't see what I'm doing wrong. Any advice?
require 'yaml'
#!/usr/bin/ruby
library_path = ARGV[0]
files_list = Dir.glob("#{library_path}/**/*")
total_capture_scatch_and_exports_size = 0
video_audit = Hash.new()
video_info = []
codecs = Hash.new()
files_list.each do |filepath|
filename = File.basename(filepath.to_s)
filepath.chomp!
puts filename
folders_to_scan = ["/capture scratch/", "/capturescratch/", "/capture-scratch/", "/capture_scratch/", "exports", "export"]
file_size = File.size(filepath)
file_extension = File.extname(filepath)
if
folders_to_scan.any? { |folder| filepath.downcase.include? folder }
if
File.file?(filepath) && filename[0] != "." && file_extension != ".TIFF" && file_extension != ".TIF" && file_extension != ".tif" && file_extension != ".tiff" && file_extension != ".jpg" && file_extension != ".jpeg" && file_extension != ".JPG" && file_extension != ".JPEG"
duration = %x[mediainfo --Inform="General;%Duration/String3%" '#{filepath}'].chomp!
format = %x[mediainfo --Inform="General;%Format%" '#{filepath}'].chomp!
commercial_name = %x[mediainfo --Inform="General;%Format_Commercial_IfAny%" '#{filepath}'].chomp!
format_profile = %x[mediainfo --Inform="General;%Format_Profile%" '#{filepath}'].chomp!
writing_library = %x[mediainfo --Inform="General;%Encoded_Library%" '#{filepath}'].chomp!
video_audit[:filepath] = filepath
video_audit[:filename] = filename
video_audit[:duration] = duration
video_audit[:file_size] = file_size
video_audit[:format] = format
video_audit[:commercial_name] = commercial_name
video_audit[:format_profile] = format_profile
video_audit[:writing_library] = writing_library
video_audit[:file_extension] = file_extension
codecs[:filename] = filename
codecs[:format] = format
codecs[:commercial_name] = commercial_name
codecs[:format_profile] = format_profile
codecs[:writing_library] = writing_library
codecs[:file_extension] = file_extension
end
end
puts video_audit.to_yaml
puts codecs
video_info << codecs
total_capture_scatch_and_exports_size += file_size
end
puts "THE VIDEO INFO IS=======>>>> #{video_info}"
puts "THE UNIQUE CODECS ARE: #{video_info.uniq!}"
#1000**3 is for gigabytes (this is how finder on OSX calculates storage on the Drobo Harddrives)use 1024**3 ofr gibibytes
puts "The total filesize is : #{total_capture_scatch_and_exports_size/(1000**3).to_f} GB"
I figured it out. I was creating new hashes outside of the loop. A new hash needed to be created for each iteration so that it could then be added to the video_info array. Then I needed to remove the bang operator when I called uniq on video_info at the end of the script. Here's my final code:
require 'json'
#developed by Maile Thiesen
#!/usr/bin/ruby
library_path = ARGV[0]
files_list = Dir.glob("#{library_path}/**/*")
total_capture_scatch_and_exports_size = 0
counter = 0
video_info = []
files_list.each do |filepath|
filename = File.basename(filepath.to_s)
codecs = {}
filepath.chomp!
folders_to_scan = ["/capture scratch/", "/capturescratch/", "/capture-scratch/", "/capture_scratch/", "exports", "export"]
file_size = File.size(filepath)
file_extension = File.extname(filepath)
if
folders_to_scan.any? { |folder| filepath.downcase.include? folder }
if
File.file?(filepath) && filename[0] != "." && file_extension != ".TIFF" && file_extension != ".TIF" && file_extension != ".tif" && file_extension != ".tiff" && file_extension != ".jpg" && file_extension != ".jpeg" && file_extension != ".JPG" && file_extension != ".JPEG"
duration = %x[mediainfo --Inform="General;%Duration/String3%" '#{filepath}'].chomp!
format = %x[mediainfo --Inform="General;%Format%" '#{filepath}'].chomp!
commercial_name = %x[mediainfo --Inform="General;%Format_Commercial_IfAny%" '#{filepath}'].chomp!
format_profile = %x[mediainfo --Inform="General;%Format_Profile%" '#{filepath}'].chomp!
writing_library = %x[mediainfo --Inform="General;%Encoded_Library%" '#{filepath}'].chomp!
codecs[:format] = format
codecs[:commercial_name] = commercial_name
codecs[:format_profile] = format_profile
codecs[:writing_library] = writing_library
codecs[:file_extension] = file_extension
total_capture_scatch_and_exports_size += file_size
counter += 1
video_info << codecs
end
end
end
puts "THE UNIQUE CODECS ARE: #{JSON.pretty_generate(video_info.uniq)}"
puts "THE TOTAL FILESIZE IS : #{total_capture_scatch_and_exports_size/(1000**3).to_f} GB"
Related
how can i make it to read the same time just one time only. this is my codes
state = station_info_state[/[^_]+/]
query = " select * from #{state} where MAIN_ID = #{main_id} order by date_taken ASC, TIME ASC " #order by date_taken ASC, TIME ASC "
state = DB["#{query}"]
#last_daily_rainfall = 0
CSV.open("./rainfall_tideda/#{#station_info_station_id}_rf.csv", "w+") do |csv|
csv << ["#{#station_info_station_id}", "INCREMENTAL", "#{#station_info_station_name}"]
state.each do |line|
time_taken = line[:'time'].to_i
time_taken = format('%04d', time_taken).to_s
simulated_time_taken = time_taken.to_s.gsub(/.{2}(?=.)/, '\0:')
date_taken = line[:'date_taken'].to_s
date_taken = Date.parse("#{date_taken}").to_s
date_taken = date_taken.gsub( "-", "/" )
current_daily_rainfall = line[:'daily_rainfall']
if(current_daily_rainfall >= 0 && current_daily_rainfall != '-9999')
this_daily_rainfall = current_daily_rainfall - #last_daily_rainfall
if(this_daily_rainfall > 0)
csv << [ "#{date_taken}", "#{simulated_time_taken}", "#{this_daily_rainfall}" ]
else
if(this_daily_rainfall != '-9999' && this_daily_rainfall == 0)
csv << [ "#{date_taken}", "#{simulated_time_taken}", "0" ]
end
if(this_daily_rainfall != '-9999' && this_daily_rainfall < 0)
csv << [ "#{date_taken}", "#{simulated_time_taken}", "#{current_daily_rainfall}" ]
end
end
#last_daily_rainfall = line[:'daily_rainfall']
end
end
end
duplicate time image
the result are shown in the image description. In the result, you can see got many duplicate time
You can make a hash which stores the dates/times you've already seen:
processed_date_times = Set.new
Then, in your iteration, add entries:
processed_date_times.add([date_taken, simulated_time_taken])
And then only add the entry if it hasn't been processed yet:
unless processed_date_times.member?([date_taken, simulated_time_taken])
# ... add row to csv
end
I have a perfectly functional piece of code that does what I want but it is really heavy and i am sure it could be greatly improved by using a nice For loop somewhere but I'm not sure how to go about it
My code is:
def helper
response = RestClient.get API_RESPONSE
check_X_0 = JSON.parse(response.body)['EXP'][0]['X']
check_Y_0 = JSON.parse(response.body)['EXP'][0]['Y']
check_X_1 = JSON.parse(response.body)['EXP'][1]['X']
check_Y_1 = JSON.parse(response.body)['EXP'][1]['Y']
check_X_2 = JSON.parse(response.body)['EXP'][2]['X']
check_Y_2 = JSON.parse(response.body)['EXP'][2]['Y']
check_X_3 = JSON.parse(response.body)['EXP'][3]['X']
check_Y_3 = JSON.parse(response.body)['EXP'][3]['Y']
check_X_4 = JSON.parse(response.body)['EXP'][4]['X']
check_Y_4 = JSON.parse(response.body)['EXP'][4]['Y']
if check_X_0 == false && check_Y_0 == true
exp_id = JSON.parse(response.body)['EXP'][0]['ABC']
elsif check_X_1 == false && check_Y_1 == true
exp_id = JSON.parse(response.body)['EXP'][1]['ABC']
elsif check_X_2 == false && check_Y_2 == true
exp_id = JSON.parse(response.body)['EXP'][2]['ABC']
elsif check_X_3 == false && check_Y_3 == true
exp_id = JSON.parse(response.body)['EXP'][3]['ABC']
elsif check_X_4 == false && check_Y_4 == true
exp_id = JSON.parse(response.body)['EXP'][4]['ABC']
else
puts 'Nothing valid - use default'
exp_id = JSON.parse(response.body)['EXP'][1]['ABC']
end
This is fairly cumbersome so can anyone help me to trim this down?
You should not parse your json 10 times in the first place. Parse it once and use the result.
rb = RestClient.get(API_RESPONSE).body['EXP']
checks = (0..4).map { |i, s| [i, rb[i]['X'], rb[i]['Y']] }
exp_id =
if found = checks.detect { |_i, f, t| !f && t }
rb[found.first]['ABC']
else
puts 'Nothing valid - use default'
rb[1]['ABC']
end
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.
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.
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