Need help with writefile line ranges within extensive file

Hi Everyone,

I have the following file that I started to work on:

class EuiiiReader

  def initialize(writefile,filename)
    @writefile = writefile
    @filename = filename
    @provnum = /^\d{1,4}\=\{/
  end

  def readfile
    File.open(@filename, "r") do |infile|
      @linenumarray = []
      while (line = infile.gets)
        if (line =~ @provnum)
          linenum = $.
          @linenumarray += [linenum]
        end
      end
    end
  end

  def writefile
    open(@writefile, "w") { |f|
      f.puts "Verifying File..."
      f.puts "================="
      File.open(@filename, "r") do |infile|
        while (line = infile.gets)
        # Need help here
        # @linenumarray contains all of the starting file lines
        # I need to output the lines + 8 lines after each one listed in
the array to an output file
        f.puts "Something to do here"
        end
      end
    }
  end
end

k = EuiiiReader.new('compare.txt', 'Italy_alternate.eu3')
k.readfile
k.writefile

···

=============

Here is my issue. I'm still trying to get better with utilizing Ruby in
various situations. Since I read a lot of files and love file readers,
I thought I would concentrate on this.

I have a simple saved game file from Europa Universallis III which
contains approximately 850,000 lines. The saved game file is currently
corrupt and I believe I know the issue and need to have a more permanent
fix in place for if it happens again.

The file will look something similar in certain segments:

....

1={
    flags={
    }
    variables={
    }
    name="Stockholm"
    owner="SCA"
    controller="SCA"
    core="SWE"
    core="SCA"
    culture=swedish

....

My class above starts with reading the entire file and locating province
number lines for 1={, 2={, etc. etc. to say 1894={. When it finds these
lines, it stores the line numbers into an array called @linenumarray.
This is done in the readfile method.

In the writefile method, I need to output to file the line and the next
8 lines after it for every line number stored in the array. So, the
file would be written to:

Verifying File...

1={
    flags={
    }
    variables={
    }
    name="Stockholm"
    owner="SCA"
    controller="SCA"
    core="SWE"
2={
    flags={
    }
    variables={
    }
    name="Stockholm"
    owner="SCA"
    controller="SCA"
    core="SWE"
etc....

My problem is I don't know how to pull the line number from the array
and attach another 8 lines to it. The commented section in the
writefile method is where the placement should occur.

Again, as this is a learning process for me, whatever best practices
should be used instead of what I've written would also be greatly
appreciated. I want to make sure I simplify and expand upon my
knowledge and not do things incorrectly. As ruby is a wonderful
language with many ways of achieving an end result, I might be taking a
more sloppy approach and for that I apologize.

Any help would be greatly appreciated.

Thanks,
--
Posted via http://www.ruby-forum.com/.

I don't know if you need the line numbers for anything else, or if you
actually need to read the file and calculate things and then write as
a separate method, but if that's not the case you can do this in a
single pass through the infile:

irb(main):033:0> File.open("resulteuiii.txt", "w") do |f|
irb(main):034:1* File.open("dataeuiii.txt") do |infile|
irb(main):035:2* while (line = infile.gets)
irb(main):036:3> if line =~ /^\d{1,4}\=\{/
irb(main):037:4> f.puts line
irb(main):038:4> 8.times {f.puts infile.gets}
irb(main):039:4> end
irb(main):040:3> end
irb(main):041:2> end

Hope this helps,

Jesus.

···

On Wed, Dec 2, 2009 at 8:15 PM, Alpha Blue <jdezenzio@gmail.com> wrote:

Hi Everyone,

I have the following file that I started to work on:

class EuiiiReader

def initialize(writefile,filename)
@writefile = writefile
@filename = filename
@provnum = /^\d{1,4}\=\{/
end

def readfile
File.open(@filename, "r") do |infile|
@linenumarray =
while (line = infile.gets)
if (line =~ @provnum)
linenum = $.
@linenumarray += [linenum]
end
end
end
end

def writefile
open(@writefile, "w") { |f|
f.puts "Verifying File..."
f.puts "================="
File.open(@filename, "r") do |infile|
while (line = infile.gets)
# Need help here
# @linenumarray contains all of the starting file lines
# I need to output the lines + 8 lines after each one listed in
the array to an output file
f.puts "Something to do here"
end
end
}
end
end

k = EuiiiReader.new('compare.txt', 'Italy_alternate.eu3')
k.readfile
k.writefile

=============

Here is my issue. I'm still trying to get better with utilizing Ruby in
various situations. Since I read a lot of files and love file readers,
I thought I would concentrate on this.

I have a simple saved game file from Europa Universallis III which
contains approximately 850,000 lines. The saved game file is currently
corrupt and I believe I know the issue and need to have a more permanent
fix in place for if it happens again.

The file will look something similar in certain segments:

....

1={
flags={
}
variables={
}
name="Stockholm"
owner="SCA"
controller="SCA"
core="SWE"
core="SCA"
culture=swedish

....

My class above starts with reading the entire file and locating province
number lines for 1={, 2={, etc. etc. to say 1894={. When it finds these
lines, it stores the line numbers into an array called @linenumarray.
This is done in the readfile method.

In the writefile method, I need to output to file the line and the next
8 lines after it for every line number stored in the array. So, the
file would be written to:

Verifying File...

1={
flags={
}
variables={
}
name="Stockholm"
owner="SCA"
controller="SCA"
core="SWE"
2={
flags={
}
variables={
}
name="Stockholm"
owner="SCA"
controller="SCA"
core="SWE"
etc....

My problem is I don't know how to pull the line number from the array
and attach another 8 lines to it. The commented section in the
writefile method is where the placement should occur.

Again, as this is a learning process for me, whatever best practices
should be used instead of what I've written would also be greatly
appreciated. I want to make sure I simplify and expand upon my
knowledge and not do things incorrectly. As ruby is a wonderful
language with many ways of achieving an end result, I might be taking a
more sloppy approach and for that I apologize.

Any help would be greatly appreciated.

Thanks,
--
Posted via http://www.ruby-forum.com/\.

Thanks mate - I appreciate the short fix.

I ended up having to do a lot more with the file and change it so I can
spot issues in certain areas. So, I've rebuilt and adapted it as such:

class EuiiiReader

  def initialize(writefile,filename)
    @writefile = writefile
    @filename = filename
    @provnum = /^\d{1,4}\=\{/
    @owner = /owner\=/
    @controller = /controller\=/
  end

  def readfile
    File.open(@filename, "r") do |infile|
      @linenumarray = []
      while (line = infile.gets)
        if (line =~ @provnum)
          linenum = $.
          @linenumarray += [linenum]
        end
      end
    end
  end

  def printmode(arg,match)
    if arg =~ match
      return true
    end
  end

  def writefile
    open(@writefile, "w") { |f|
      f.puts "Verifying File..."
      f.puts "================="
      g = File.open(@filename, "r")
      a = g.readlines
      @linenumarray.each do |segment|
        badowner = 0
        badcontroller = 0
        f.puts "Line number #{segment} and #{a[segment - 1]}"
        if a[segment+5] =~ @owner || a[segment+6] =~ @owner ||
a[segment+7] =~ @owner
          f.puts printmode(a[segment+5],@owner) ? a[segment+5] : '' if
a[segment+5] =~ @owner
          f.puts printmode(a[segment+6],@owner) ? a[segment+6] : '' if
a[segment+6] =~ @owner
          f.puts printmode(a[segment+7],@owner) ? a[segment+7] : '' if
a[segment+7] =~ @owner
        else
          badowner = 1
        end
        if a[segment+6] =~ @controller || a[segment+7] =~ @controller ||
a[segment+8] =~ @controller
          f.puts printmode(a[segment+6],@controller) ? a[segment+6] : ''
if a[segment+6] =~ @controller
          f.puts printmode(a[segment+7],@controller) ? a[segment+7] : ''
if a[segment+7] =~ @controller
          f.puts printmode(a[segment+8],@controller) ? a[segment+8] : ''
if a[segment+8] =~ @controller
        else
          badcontroller = 1
        end
        if (badowner + badcontroller) == 1
          f.puts 'FOUND a mismatch for owner/controller'
          if badowner == 1
            f.puts 'Owner not found'
          else
            f.puts 'Controller not found'
          end
        elsif (badowner + badcontroller) == 2
          f.puts 'No Owners or Controllers for Province'
        else

···

#
        end
      end
    }
  end
end

k = EuiiiReader.new('compare.txt', 'Italy_alternate.eu3')
k.readfile
k.writefile

--
Posted via http://www.ruby-forum.com/.

Here you are not closing the file.

Use a = File.readlines(@filename)

instead.

Jesus.

···

On Wed, Dec 2, 2009 at 10:08 PM, Alpha Blue <jdezenzio@gmail.com> wrote:

Thanks mate - I appreciate the short fix.

I ended up having to do a lot more with the file and change it so I can
spot issues in certain areas. So, I've rebuilt and adapted it as such:

 g = File\.open\(@filename, &quot;r&quot;\)
 a = g\.readlines

Jesús Gabriel y Galán wrote:

Here you are not closing the file.

Use a = File.readlines(@filename)

instead.

Jesus.

Thanks mate - appreciate it. I'm cleaning it up now.

···

--
Posted via http://www.ruby-forum.com/\.