1

I have created this search and replace program. But I want to make changes to it, so I can do a search and replace for multiple files at once. Now, is there a way so I have the option to select multiple files at once from any folder or directory that I choose.

The code that helps me to select files using file dialog window is given below, but is giving errors. can you help me to correct it? The FULL traceback error is :

Traceback <most recent call last>:
 File "replace.py", line 24, in <module>
 main()
File "replace.py", line 10, in main
 file = tkFileDialog.askopenfiles(parent=root,mode='r',title='Choose a file')
File "d:\Python27\lib\lib-tk\tkFileDialog.py",line 163, in askopenfiles
   ofiles.append(open(filename,mode))
IOError: [Errno 2] No such file or directory: u'E'

And here's the code: I finally got this code to work I changed 'file' to 'filez' and 'askopenfiles' to askopenfilenames'. and I was able to replace the word in my chosen file. the only thing is that it doesnt work when I choose 2 files. maybe I should add in a loop for it to work for multiple files. But, this was a kind of trial and error and I want to be able to really know why it worked. Is there a book or something that will help me to fully understand this tkinter and file dialog thing? anyways, I have changed the code below to show the working code now:

#replace.py
import string
def main():
    #import tkFileDialog
    #import re
    #ff = tkFileDialog.askopenfilenames()
    #filez = re.findall('{(.*?)}', ff)
    import Tkinter,tkFileDialog
    root = Tkinter.Tk()
    filez = tkFileDialog.askopenfilenames(parent=root,mode='r',title='Choose a file')
#filez = raw_input("which files do you want processed?")
f=open(filez,"r")
data=f.read()
w1=raw_input("what do you want to replace?")
w2= raw_input("what do you want to replace with?")
print data
data=data.replace(w1,w2)
print data
f=open(filez,"w")
f.write(data)
f.close()


main()

EDIT: One of the replies below gave me an idea about file dialog window and now I am able to select multiple files using a tkinter window, but I am not able to go ahead with the replacing. it's giving errors. I tried out different ways to use file dialog and the different ways are giving different errors. Instead of deleting one of the ways, I have just put a hash sign in front so as to make it a comment, so you guys are able to take a look and see which one would be better.

13
  • You should really post the section of code that is giving you the errors with the fileDialogBox. Also, you should post the errors themselves. And since that would technically be a different question, you should turn that into a new post Commented Nov 27, 2012 at 15:20
  • seems like you were writing this comment, while I was adding the details you wanted. I had thought of making a new post, but then I thought people will downvote or block this question because it's a duplicate or something like that. Commented Nov 27, 2012 at 15:22
  • This question was about selecting multiple files. Then answer was "use tkFileDialog". The question you now have is "how do I get results out of tkFileDialog correctly?". Realistically, you could turn it into another post, but it does stand a chance of being closed, for it is not asked correctly, the first comments would include "have you looked at the documentation? what did you not understand from there?" Commented Nov 27, 2012 at 15:26
  • well, I couldnt find the answer to my question in the documentation. Commented Nov 27, 2012 at 15:31
  • then, you have a valid question Commented Nov 27, 2012 at 15:32

5 Answers 5

2

Maybe you should take a look at the glob module, it can make finding all files matching a simple pattern (such as *.txt) easy.

Or, easier still but less user-friendly, you could of course treat your input filename filez as a list, separating filenames with space:

for fn in filez.split():
  # your code here, replacing filez with fn
Sign up to request clarification or add additional context in comments.

2 Comments

I would do it take list of files from stdin and use: $ ls *.txt > your_script.py for example
@crow16384 Why would you want to overwrite your script instead of pipng the data into the process running your script (with |)?
1

You probably want to have a look at glob module.

An example that handles "*" in your input:

#replace.py
import string
import glob

def main():
    filez = raw_input("which files do you want processed?")
    filez_l = filez.split()
    w1=raw_input("what do you want to replace?")
    w2= raw_input("what do you want to replace with?")
    # Handle '*'  e.g. /home/username/* or /home/username/mydir/*/filename
    extended_list = []
    for filez in filez_l:
        if '*' in filez:
           extended_list += glob.glob(filez)
        else:
           extended_list.append(filez)
    #print extended_list
    for filez in extended_list:
        print "file:", filez
        f=open(filez,"r")
        data=f.read()
        print data
        data=data.replace(w1,w2)
        print data
        f=open(filez,"w")
        f.write(data)
        f.close()
main()

Comments

1

I would rather use the command line instead of input.

#replace.py

def main():
    import sys
    w1 = sys.argv[1]
    w2 = sys.argv[2]
    filez = sys.argv[3:]
    # ***
    for fname in filez:
        with open(fname, "r") as f:
            data = f.read()
            data = data.replace(w1, w2)
            print data
        with open(fname, "w") as f:
            f.write(data)
if __name__ == '__main__':
    main()

So you can call your program with

 replace.py "old text" "new text" *.foo.txt

or

 find -name \*.txt -mmin -700 -exec replace.py "old text" "new text" {} +

If you think of a dialog window, you could insert the following at the position with ***:

if not filez:
    import tkFileDialog
    import re
    ff = tkFileDialog.askopenfilenames()
    filez = re.findall('{(.*?)}', ff)

5 Comments

yes, that's it! a dialog window is what I wanted. I just didnt know it was called a dialog window. but when I am using your code and have input the code for the dialog window at the **** position, I get an error when I run. the error is:traceback error, in line 19 which is main() and another error in line 3: which is the line w1 = sys.argv[1] the error is IndexError: list index out of range. so, what should be done here?
Well, of couse you should provide the "old text" and the "new text" on the command line. This gets you rid of the IndexError. As you don't tell what's wrong on line 19, I cannot help.
well, I mentioned the traceback error in line 19. but I think you have already given me the idea and I will be able to read some more and be able to do it, I hope.
A traceback is (holpefully) included in every exception. The question is what the type of the error is indeed.
Oh, I think I got it! You get one traceback (list of function calls) which includes both these lines. The real error is just the said IndexError.
0

Why not put the program into a for-loop:

def main():
    files = raw_input("list all the files do you want processed (separated by commas)")
    for filez in files.split(','):
        f=open(filez,"r")
        data=f.read()
        f.close()
        w1=raw_input("what do you want to replace?")
        w2= raw_input("what do you want to replace with?")
        print data
        data=data.replace(w1,w2)
        print data
        f=open(filez,"w")
        f.write(data)
        f.close()

main()

3 Comments

I really dont want to list all the files that I want replaced, because I could have a 100 files that I want to work on and writing the names of the 100 files could be very tedious.
why not put them all in one directory and let your python script run the replace for all files in that directory?
hmm, now that's a good idea too! But I also want to learn python and I want to be able to do the file dialog thing too. Actually, with another reply above I got an idea and have used it too. And actually, now I am able to select files the way I want, but I am getting an error I click open after the selection. I'll just edit my question to show the code now and maybe you could help me out.
0

A good trick to open huge files line by line in python:

contents =  map(lambda x: x.next().replace("\n",""),map(iter,FILES))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.