Scanning strings, backward?

Hi,

I would like to automate a code cleanup task which involves
finding warning messages like,

Warning: …/…/LibF90/bc_inviscid.f90, line 1707:
DT explicitly imported into BC_INVISCID_FLUX but not used
detected at BC_INVISCID_FLUX@

and removing the offending unused import.

So, the tasks are roughly,

  1. Goto line 1707 of the file
  2. Search backward until line.match /\Wdt\W/i
  3. Remove /dt/i

I’m stuck on an elegant, i.e., Ruby, way to do the first
two steps. Please point me toward the glittering light.

Thanks,

Bil K. wrote:

So, the tasks are roughly,

  1. Goto line 1707 of the file
  2. Search backward until line.match /\Wdt\W/i
  3. Remove /dt/i

I’m stuck on an elegant, i.e., Ruby, way to do the first
two steps. Please point me toward the glittering light.

For 1) Assuming the lines aren’t fixed length: Read in the entire file
into an array (using IO#readlines), in which case you can skip straight
to the line you want, or counting line by line until you find the one
you want.

For 2) Any particular reason why you need to search backwards? My
suggestion would be to look at String#gsub - that will help you handle
both 2) and 3) in one go.

Vidar

Vidar H. wrote:

For 1) Assuming the lines aren’t fixed length: Read in the entire file

For 2, can’t you reverse the line and search forwards?

Bil K. wrote:


Bil K.
http://fun3d.larc.nasa.gov

Wait a minute … is the file you’re editing always a Fortran source?
Why not just comment out the offending line rather than removing it?
Otherwise, removing a line changes the position number of every line
following it.

On Oct 11, 2006, at 6:05 AM, Bil K. wrote:

So, the tasks are roughly,

  1. Goto line 1707 of the file
  2. Search backward until line.match /\Wdt\W/i

Would my File::ReadBackwards port help here?

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/177347

I’ve needed it twice myself lately, so I’m happy to gemify it, if it
will help you.

James Edward G. II

On Oct 11, 2006, at 7:35 AM, Vidar H. wrote:

For 1) Assuming the lines aren’t fixed length: Read in the entire file
into an array (using IO#readlines), in which case you can skip
straight
to the line you want, or counting line by line until you find the one
you want.

For 2) Any particular reason why you need to search backwards? My
suggestion would be to look at String#gsub - that will help you handle
both 2) and 3) in one go.

I like this idea, but I would suggest using a hash rather than an
array. Hash the lines keyed to their line number. Then you can search
any which way you like.

Regards, Morton

Morton G. wrote:

I like this idea, but I would suggest using a hash rather than an
array. Hash the lines keyed to their line number. Then you can search
any which way you like.

I don’t see what this would give you. An array of the lines in the
order read would be keyed to the line number. Assuming the Ruby array
implementation is sane using an array should be faster, and also has
the advantage that IO#readlines does all the work of reading the lines
in from file and returning a ready populated array.

Vidar

On Oct 11, 2006, at 10:25 AM, Vidar H. wrote:

Morton G. wrote:

I like this idea, but I would suggest using a hash rather than an
array. Hash the lines keyed to their line number. Then you can search
any which way you like.

I don’t see what this would give you. An array of the lines in the
order read would be keyed to the line number. Assuming the Ruby array
implementation is sane using an array should be faster, and also has
the advantage that IO#readlines does all the work of reading the lines
in from file and returning a ready populated array.

It’s a worthless idea. Somedays my brain behaves like a fried egg
even through I don’t do drugs. Today seems to be one of those days
.

Regards, Morton

On 2006.10.11 20:05, Bil K. wrote:

So, the tasks are roughly,

  1. Goto line 1707 of the file

File.readlines for reasonably sized files, f.each_with_index
for skipping over until 1707.

  1. Search backward until line.match /\Wdt\W/i
  2. Remove /dt/i

Combine these by anchoring.

line.sub /(.\W)dt(\W.)$/i, ‘\1\2’

If the \W are spaces, strip one of them out.

On 2006.10.12 23:20, Rick DeNatale wrote:

  1. Remove /dt/i

Combine these by anchoring.

line.sub /(.\W)dt(\W.)$/i, ‘\1\2’

If the \W are spaces, strip one of them out.

I believe that the OP doesn’t want to search line 1707 backwards for
dt, he want’s to search the file backwards starting at line 1707 (or
maybe 1706) for a line containing dt.

Ah! /m :smiley:

Granted in that case it would be simplest to use #rindex or to reverse
the String altogether.

On 10/11/06, Eero S. [email protected] wrote:

and removing the offending unused import.

Combine these by anchoring.

line.sub /(.\W)dt(\W.)$/i, ‘\1\2’

If the \W are spaces, strip one of them out.

I believe that the OP doesn’t want to search line 1707 backwards for
dt, he want’s to search the file backwards starting at line 1707 (or
maybe 1706) for a line containing dt.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/