[Tutor] Find multiple lines in a file

Kent Johnson kent37 at tds.net
Wed Nov 9 12:08:48 CET 2005


Bill Burns wrote:
> I have a PostScript file which contains the following lines (the numbers
> are for reference only and are *not* in the file):
> 
> 1 <<
> 2   /Policies <<
> 3     /PageSize 3
> 4   >>
> 5 >> setpagedevice
>  
> I want to open the the file and read it, find these five lines and then
> replace the lines with something different.
> 
> Here's some code I'm using to replace just a *single* line in the
> PostScript file (Note - I'm changing the BoundingBox which is in the
> same file, but is *not* one of the five lines above).
> 
> <code>
> import fileinput
> 
> class ChangeBBox:
>      pass
> 
>      def getBBox(self, filename):
>              f = open(filename, "rb")
>              buffer = 1000
>              tmp = f.readlines(buffer)
>              f.close()
>              for line in tmp:
>                  if line.startswith('%%BoundingBox:'):
>                      return line.strip()
> 
>      def modifyBBox(self, filename):
>          old = self.getBBox(filename)
>          new = '%%BoundingBox: 0 0 1296 1728'
>          for line in fileinput.input(filename, inplace=1):
>              print line.replace(old, new),
> </code>

A few comments on the above..
- You don't need to put these functions in a class, the class isn't adding any value. (OK, it puts the two functions in a single namespace but a module would be more appropriate for that.)
- The 'pass' statement is not needed.
- You are adding blank lines to the file - the lines returned by fileinput.input() contain newlines, and print adds another. Avoid this using sys.stdout.write() instead of print.
- A simpler way to iterate the lines in a file is
  for line in f:

In fact the whole pre-search is really not needed, you could write this as (untested!):
import fileinput, sys
def modifyBBox(filename):
  for line in fileinput.input(filename, inplace=1):
    if line.startswith('%%BoundingBox:'):
      line = '%%BoundingBox: 0 0 1296 1728\n'
    sys.stdout.write(line)

> Can anyone offer suggestions on how to find all five lines? I don't
> think I'll have a problem replacing the lines, it's just getting them
> all into one variable that stumping me :-)

OK, none of my suggestions gets you closer to this...the simplest way is if you can read the whole file into memory. Then you can just replace the strings in place and write it out again. For example:

oldPolicies = '''<<
  /Policies <<
    /PageSize 3
  >>
>> setpagedevice'''

newPolicies = 'something completely different'

f = open(filename)
data = f.read()
f.close()
data.replace(oldPolicies, newPolicies)
f = open(filename, 'w')
f.write(data)
f.close()

Replacing the bounding box is a little trickier because you have to search for the end of line. You can do this with a regular expression or a couple of find() calls on the string. I'm out of time now so maybe someone else will fill that in.

Kent

-- 
http://www.kentsjohnson.com



More information about the Tutor mailing list