Writing to a certain line?

T

Tommy B

I was wondering if there was a way to take a txt file and, while
keeping most of it, replace only one line. See, I'd have a file like:

Tommy 555
Bob 62
Joe 529

And I'd want to set it to be:

Tommy 555
Bob 66
Joe 529

Is there any easy way to do this?
 
R

Rene Pijlman

Tommy B:
I was wondering if there was a way to take a txt file and, while
keeping most of it, replace only one line.

You'd need to read the file and parse it, to find the start position of
the line you want to change. Then seek output to that position and write
and flush the changes. You must keep the file locked during this
operation, to prevent other processes from changing the file in between
these steps. You can only replace a string with a string of the same
length.
http://docs.python.org/lib/bltin-file-objects.html
 
B

bruno at modulix

Tommy said:
I was wondering if there was a way to take a txt file and, while
keeping most of it, replace only one line.

<meta>
This is a FAQ (while I don't know if it's in the FAQ !-), and is in no
way a Python problem. FWIW, this is also CS101...
</meta>

You can't do this in place with a text file (would be possible with a
fixed-length binary format).

The canonical way to do so - whatever the language, is to write the
modified version in a new file, then replace the old one.

import os
old = open("/path/to/file.txt", "r")
new = open("/path/to/new.txt", "w")
for line in old:
if line.strip() == "Bob 62"
line = line.replace("62", "66")
new.write(line)
old.close()
new.close()
os.rename("/path/to/new.txt", "/path/to/file.txt")

If you have to do this kind of operation frequently and don't care about
files being human-readable, you may be better using some lightweight
database system (berkeley, sqlite,...) or any other existing lib that'll
take care of gory details.

Else - if you want/need to stick to human readable flat text files - at
least write a solid librairy handling this, so you can keep client code
free of technical cruft.

HTH
 
R

Rene Pijlman

bruno at modulix:
You can't do this in place with a text file (would be possible with a
fixed-length binary format).

More precise: it's possible with any fixed-length change, in both binary
and text files, with both fixed and variable formats.
 
B

bruno at modulix

Rene said:
bruno at modulix:



More precise: it's possible with any fixed-length change, in both binary
and text files, with both fixed and variable formats.
Granted. But this is somewhat limited in what you can do when working
with text files...
 
G

gene tani

bruno said:
Else - if you want/need to stick to human readable flat text files - at
least write a solid librairy handling this, so you can keep client code
free of technical cruft.

HTH

for human readable, you might want to look at reading and writing dicts
in YAML and SYCK libs, which is what this looks like
 
T

Tommy B

bruno said:
<meta>
This is a FAQ (while I don't know if it's in the FAQ !-), and is in no
way a Python problem. FWIW, this is also CS101...
</meta>

You can't do this in place with a text file (would be possible with a
fixed-length binary format).

The canonical way to do so - whatever the language, is to write the
modified version in a new file, then replace the old one.

import os
old = open("/path/to/file.txt", "r")
new = open("/path/to/new.txt", "w")
for line in old:
if line.strip() == "Bob 62"
line = line.replace("62", "66")
new.write(line)
old.close()
new.close()
os.rename("/path/to/new.txt", "/path/to/file.txt")

If you have to do this kind of operation frequently and don't care about
files being human-readable, you may be better using some lightweight
database system (berkeley, sqlite,...) or any other existing lib that'll
take care of gory details.

Else - if you want/need to stick to human readable flat text files - at
least write a solid librairy handling this, so you can keep client code
free of technical cruft.

HTH

Umm... I tried using this method and it froze. Infiinite loop, I'm
guessing.
 
F

Fredrik Lundh

Umm... I tried using this method and it froze. Infiinite loop, I'm
guessing.

you have an infinitely large disk with an infinitely large file on it?

</F>
 
J

John Machin

Umm... I tried using this method and it froze. Infiinite loop, I'm
guessing.

Don't guess.

Instead:

(1) Put some print statements into your code to show what is happening:
(a) before start of loop (b) one or more salient points inside loop (c)
at (expected) loop termination point.

(2) If that doesn't point you at the problem, ask again, showing the
actual whole .py file that you ran -- copy/paste, don't re-type what you
thought you might have run :)

It would also help if you described what "froze" means. Evidence of disk
activity? Evidence of CPU activity? Did recovery involve merely closing
the process's window, or did you need to re-boot?

Also potentially helpful in getting better help: what version of Python;
what operating system; are you running your code in an IDE (e.g. IDLE)
or at the command line?

HTH,
John
 
B

bruno at modulix

Tommy said:
bruno at modulix wrote:
(snip)
(snip)

Umm... I tried using this method and it froze. Infiinite loop, I'm
guessing.

Wrong guess - unless, as Fredrik suggested, you have an infinite disk
with an infinite file on it. If so, please share with, we would be
*very* interested !-)

Seriously : a for loop can only become an infinite loop if the iterable
is infinite. AFAIK, file objects (created from regular files on a
standard filesystem) are definitively not infinite.

Problem is elsewhere. But since you prefered to guess - instead of
providing relevant informations - we just can't help.
 
C

Christophe

bruno at modulix a écrit :
Wrong guess - unless, as Fredrik suggested, you have an infinite disk
with an infinite file on it. If so, please share with, we would be
*very* interested !-)

Use /dev/zero as source and /dev/null as destination :D
 
F

Fredrik Lundh

Christophe said:
Use /dev/zero as source and /dev/null as destination :D

have you tried looping over an endless null-byte stream?

on a random Linux server, this statement
.... print len(line)
....

terminates without printing anything after about three seconds, which is
a bit odd. in contrast,

raises a MemoryError exception after about 10 seconds. hmm. looks like
a bug in the file iterator, really...

</F>
 
J

Jack Diederich

have you tried looping over an endless null-byte stream?

on a random Linux server, this statement

... print len(line)
...

terminates without printing anything after about three seconds, which is
a bit odd. in contrast,


raises a MemoryError exception after about 10 seconds. hmm. looks like
a bug in the file iterator, really...

svn log Objects/fileobject.c

r43506 | georg.brandl | 2006-03-31 15:31:02 -0500 (Fri, 31 Mar 2006) | 2 lines

Bug #1177964: make file iterator raise MemoryError on too big files


So it always the error on the trunk.

-Jack
 
J

John Savage

Tommy B said:
I was wondering if there was a way to take a txt file and, while
keeping most of it, replace only one line. See, I'd have a file like:
...

Is there any easy way to do this?

An easy way? If you know how many bytes in from the start of the file
your desired changes are to be positioned, the utility of choice is
the strange but wonderful "dd" for Unix, MSwindows, MSDOS, etc.
That's its name: dd. Are you planning to execute a call to dd from within
a python program? Of course, you are constrained to substituting N bytes
with another N bytes, exactly.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top