0

I need to find every instance of "translate" in a text file and replace a value 4 lines after finding the text:

"(many lines)
                }
            }   
        translateX xtran        
            {   
            keys    
                {
                k  0  0.5678
                }
            }   
(many lines)"

The value 0.5678 needs to be 0. It will always be 4 lines below the "translate" string The file has up to about 10,000 lines. example text file name: 01F.pz2.

I'd also like to cycle through the folder and repeat the process for every file with the pz2 extension (up to 40).

Any help would be appreciated!

Thanks.

Paolo
  • 20,112
  • 21
  • 72
  • 113
  • 1
    And you've tried ... ? Show some effort, errors, or _code_ that you've put into solving the problem. – g.d.d.c Jan 21 '13 at 05:01

2 Answers2

1

I'm not quite sure about the logic for replacing 0.5678 in your file, therefore I use a function for that - change it to whatever you need, or explain more in details what you want. Last number in line? only floating-point number?

Try:

import os    

dirname = "14432826"
lines_distance= 4

def replace_whatever(line):
    # Put your logic for replacing here
    return line.replace("0.5678", "0")

for filename in filter(lambda x:x.endswith(".pz2") and not x.startswith("m_"), os.listdir(dirname)):
    print filename
    with open(os.path.join(dirname, filename), "r") as f_in, open(os.path.join(dirname,"m_%s" % filename), "w") as f_out:
        replace_tasks = []
        for line in f_in:
            # search marker in line
            if line.strip().startswith("translate"):
                print "Found marker in", line,
                replace_tasks.append(lines_distance)                
            # replace if necessary
            if len(replace_tasks)>0 and replace_tasks[0] == 0:
                del replace_tasks[0]
                print "line to change is", line,
                line_to_write = replace_whatever(line)
            else:
                line_to_write = line
            # Write to output
            f_out.write(line_to_write)
            # decrease counters
            for i, task in enumerate(replace_tasks):
                replace_tasks[i] -= 1

The comments within the code should help understanding. The main concept is the list replace_tasks that keeps record of when the next line to modify will come.

Remarks: Your code sample suggests that the data in your file are structured. It will definitely be saver to read this structure and work on it instead of search-and-replace approach on a plain text file.

Thorsten Kranz
  • 12,492
  • 2
  • 39
  • 56
0

Thorsten, I renamed my original files to have the .old extension and the following code works:

import os
target_dir = "."


# cycle through files
for path, dirs, files in os.walk(target_dir):
    # file is the file counter
    for file in files:
        # get the filename and extension
        filename, ext = os.path.splitext(file)
        # see if the file is a pz2
        if ext.endswith('.old') :
            # rename the file to "old"
            oldfilename = filename + ".old"
            newfilename = filename + ".pz2"
            old_filepath = os.path.join(path, oldfilename)
            new_filepath = os.path.join(path, newfilename)
            # open the old file for reading
            oldpz2 = open (old_filepath,"r")
            # open the new file for writing
            newpz2 = open (new_filepath,"w")
            # reset changeline
            changeline = 0
            currentline = 0
            # cycle through old lines
            for line in oldpz2 :
                currentline = currentline + 1
                if line.strip().startswith("translate"):
                        changeline = currentline + 4
                if currentline == changeline :
                    print >>newpz2,"                k  0  0"
                else :
                    print >>newpz2,line