views:

489

answers:

9

I'm trying to replace a string in all the files within the current directory. for some reason, my temp file ends up blank. It seems my .write isn't working because the secondfile was declared outside its scope maybe? I'm new to python, so still climbing the learning curve...thanks!

edit: I'm aware my tempfile isn't being copied currently. I'm also aware there are much more efficient ways of doing this. I'm doing it this way for practice. If someone could answer specifically why the .write method fails to work here, that would be great. Thanks!

import os
import shutil


for filename in os.listdir("."):
    file1 = open(filename,'r')  
    secondfile = open("temp.out",'w')
    print filename
    for line in file1:
      line2 = line.replace('mrddb2.','shpdb2.')
        line3 = line2.replace('MRDDB2.','SHPDB2.')
        secondfile.write(line3)
    print 'file copy in progress'
    file1.close()
    secondfile.close()
A: 

Firstly,

you have forgotten to copy the temp file back onto the original.

Secondly:

use sed -i or perl -i instead of python.

For instance:

perl -i -pe 's/mrddb2/shpdb2/;s/MRDDB2/SHPDB2/' *
Alex Brown
Why was I bumped for this reply? Have I violated a rule by recommending a different language?
Alex Brown
Alex, it's pretty obvious this is a Python-specific question (either for a course or just general edification). Obviously sed is more generally useful.
Matthew Flaschen
Hang on, the first sentence is:I'm trying to replace a string in all the files within the current directoryIf someone in my workplace said this, I would tell them what I would do - perl.
Alex Brown
A: 

wow...quick reply..thanks!

just a note: I'm aware my tempfile isn't being copied currently. I'm also aware there are much more efficient ways of doing this. I'm doing it this way for practice. If someone could answer specifically why the .write method fails to work here, that would be great. Thanks!

this isn't an answer... add it as a comment to your question or append it to it!
Beau Martínez
You also ought to delete this "answer" now that you've updated your question. :-)
Ben Blank
A: 

I don't have the exact answer for you, but what might help is to stick some print lines in there in strategic places, like print each line before it was modified, then again after it was modified. Then place another one after the line was modified just before it is written to the file. Then just before you close the new file do a:

print secondfile.read()

You could also try to limit the results you get if there are too many for debugging purposes. You can limit string output by attaching a subscript modifier to the end, for example:

print secondfile.read()[:n]

If n = 100 it will limit the output to 100 characters.

Wayne Koorts
+2  A: 

Your code (correctly indented, though I don't think there's a way to indent it so it runs but doesn't work right) actually seems right. Keep in mind, temp.out will be the replaced contents of only the last source file. Could it be that file is just blank?

Matthew Flaschen
That's my guess as well... What would the correct way of opening it be to get a copy of the contents of all files, not just the last? "w+"? "a"? "a+"?
Jaime
a would allow you to concatenate all the replacement files into the result.
Matthew Flaschen
+4  A: 

Just glancing at the thing, it appears that your problem is with the 'w'.

It looks like you keep overwriting, not appending.

So you're basically looping through the file(s),
and by the end you've only copied the last file to your temp file.

You'll may want to open the file with 'a' instead of 'w'.

Adam Bernier
This is not quite right. It writes the full contents of the first file, then overwrites it with the full contents of the second file, etc.
Matthew Flaschen
Thank you Matt. You're absolutely right. I've corrected my wording.
Adam Bernier
+1 for the only useful answer here. It means that if the last file is empty, temp.out will be empty at the end of the loop.
NicDumZ
A: 

if your code is actually indented as showed in the post, the write is working fine. But if it is failing, the write call may be outside the inner for loop.

Alexandre Rademaker
A: 

Just to make sure I wasn't really missing something, I tested the code and it worked fine for me. Maybe you could try continue for everything but one specific filename and then check the contents of temp.out after that.

import os

for filename in os.listdir("."):
    if filename != 'findme.txt': continue
    print 'Processing', filename
    file1 = open(filename,'r')
    secondfile = open("temp.out",'w')
    print filename
    for line in file1:
        line2 = line.replace('mrddb2.','shpdb2.')
        line3 = line2.replace('MRDDB2.','SHPDB2.')
        print 'About to write:', line3
        secondfile.write(line3)
    print 'Done with', filename
    file1.close()
    secondfile.close()

Also, as others have mentioned, you're just clobbering your temp.out file each time you process a new file. You've also imported shutil without actually doing anything with it. Are you forgetting to copy temp.out back to your original file?

Mark42
A: 

I noticed sometimes it will not print to file if you don't have a file.close after file.write.

For example, this program never actually saves to file, it just makes a blank file (unless you add outfile.close() right after the outfile.write.)

outfile=open("ok.txt","w")

fc="filecontents"

outfile.write(fc.encode("utf-8"))


while 1:

    print "working..."
A: 

@OP, you might also want to try fileinput module ( this way, you don't have to use your own temp file)

import fileinput
for filename in os.listdir("."):
    for line in fileinput.FileInput(filename,inplace=1):
        line = line.strip().replace('mrddb2.','shpdb2.')
        line = line.strip().replace('MRDDB2.','SHPDB2.')
        print line

set "inplace" to 1 for editing the file in place. Set to 0 for normal print to stdout

ghostdog74