Python

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • Find multiple lines in a file

    3 answers - 2054 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    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
    These lines never change and are always formatted like this (at least in
    the PostScript files that I'm generating with tiff2ps).
    I want to open the the file and read it, find these five lines and then
    replace the lines with something different.
    I understand how to open and read the file. I have no problems finding
    and changing a *single* line, but I can not figure out how to find the
    *multiple* lines (and put them into one variable).
    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>
    The above code uses the fileinput module which makes it really nice for
    modifying a file 'inplace'. I use the code like this
    c = ChangeBBox()
    c.modifyBBox(somePostScriptFile.ps)
    and it works great, but it's really simple because it only has to modify
    *one* 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 :-)
    Thanks,
    Bill
    Tutor maillist - Tutor (AT) python (DOT) org
  • No.1 | | 3079 bytes | |

    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. (K, 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 :-)

    K, none of my suggestions gets you closer to thisthe 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
  • No.2 | | 4155 bytes | |

    >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. (K, 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 :-)


    K, none of my suggestions gets you closer to thisthe 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

    Tutor maillist - Tutor (AT) python (DOT) org
  • No.3 | | 1609 bytes | |

    [Kent wrote]
    K, none of my suggestions gets you closer to thisthe 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()

    Hi Kent,

    I just tested the following code and it works like a champ :-)

    filename = r'C:\TEST.ps'

    old = '''<<
    /Policies <<
    /PageSize 3
    >>

    >setpagedevice'''


    new = '''<<
    /EndPage
    { exch pop
    0 eq
    { gsave
    initmatrix
    save
    850 1250 moveto 45 rotate 0 setgray
    /Helvetica 25 selectfont (CAUTIN - D NT SCALE!) true charpath .2
    setlinewidth stroke
    restore
    true
    }
    { false }
    ifelse
    } bind
    >setpagedevice'''


    f = open(filename)
    data = f.read()
    f.close()
    newData = data.replace(old, new)
    f = open(filename, 'w')
    f.write(newData)
    f.close()

    Thanks again for your help!!

    Bill

    Tutor maillist - Tutor (AT) python (DOT) org

Re: Find multiple lines in a file


max 4000 letters.
Your nickname that display:
In order to stop the spam: 3 + 2 =
QUESTION ON "Python"

EMSDN.COM