[Tutor] Find multiple lines in a file
Bill Burns
billburns at pennswoods.net
Wed Nov 9 13:44:23 CET 2005
>> 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.
Yeah, I have the above code in its own module. I've been trying to
'clean-up' my main module (which has way too much 'stuff' going on in
it) and put logical parts & pieces together in separate modules.
Not sure how that pass statement got in there.. must have been from
testing at some point, oops :-)
> - 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.
Much nicer than print! I'll change it.
> - 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)
Much simpler, will take a look at this.
>
>> 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.
I'll test out this suggestion later, unfortunately, I've gotta get to
work :-(
Thanks for the reply, Kent!! I really appreciate it!
Bill
More information about the Tutor
mailing list