views:

131

answers:

4

Hi,

im trying to create a script that opens a file and replace every 'hola' with 'hello'.

f=open("kk.txt","w")

for line in f:
  if "hola" in line:
      line=line.replace('hola','hello')

f.close()

But im getting this error:

Traceback (most recent call last):
File "prueba.py", line 3, in for line in f: IOError: [Errno 9] Bad file descriptor

Any idea?

Javi

+4  A: 

You've opened the file for writing, but you're reading from it. Open the original file for reading and a new file for writing. After the replacement, rename the original out and the new one in.

Ignacio Vazquez-Abrams
+3  A: 

You could also have a look at the with statement.

Wieland H.
+8  A: 
open('test.txt', 'w').write(open('test.txt', 'r').read().replace('hola', 'hello'))

Or if you want to properly close the file:

with open('test.txt', 'r') as src:
    src_text = src.read()

with open('test.txt', 'w') as dst:
    dst.write(src_text.replace('hola', 'hello'))
Max Shawabkeh
It's all fun and games until you open a 1GB file on a 256MB machine...
Ignacio Vazquez-Abrams
True, but for a beginner, this is the most simple and straightforward way.
Max Shawabkeh
Answer shadows 'input' built-in, maybe src_text might be a better variable name?
Paul McGuire
@Paul: Might as well. Edited.
Max Shawabkeh
+4  A: 

Your main issue is that you're opening the file for writing first. When you open a file for writing, the contents of the file are deleted, which makes it quite difficult to do replacements! If you want to replace words in the file, you have a three-step process:

  1. Read the file into a string
  2. Make replacements in that string
  3. Write that string to the file

In code:

# open for reading first since we need to get the text out
f = open('kk.txt','r')
# step 1
data = f.read()
# step 2
data = data.replace("hola", "hello")
f.close()
# *now* open for writing
f = open('kk.txt', 'w')
# step 3
f.write(data)
f.close()
Daniel G
We should teach beginners to use 'with' from the start - see Max Shawabkeh's answer.
Paul McGuire
@paul I don't disagree; however, since the user was already having difficulty with the concept of manipulating files, I originally decided to keep my answer as close to his original code as possible. Since a subsequent question by the user indicated Python 2.5 (which requires a special import from the `__future__`), I figured I might as well not change it. The other answer is, of course, equally correct if not as explicit.
Daniel G
And beware that simple replace will a) not match "Hola" and give "Hello", and b) *will* match 'hola' in 'scholar' giving 'schellor'.
Paul McGuire