Prepare a line for an existing file in Python

I need to add one line to the first line of a text file, and it seems that only options that are more suitable for me than expected from python are available to me. Something like that:

f = open('filename','r') temp = f.read() f.close() f = open('filename', 'w') f.write("#testfirstline") f.write(temp) f.close() 

Is there an easier way? In addition, I see this example with two descriptors more often than opening one descriptor for reading and writing ("r +") - why is this?

+63
python prepend
Dec 15 '10 at 19:59
source share
11 answers

Python simplifies many things and contains libraries and wrappers for many common operations, but the goal is not to hide fundamental truths.

The basic truth that you encounter is that you usually cannot add data to an existing flat structure without rewriting the entire structure. This is true regardless of language.

There are ways to save the file descriptor or make your code less readable, many of which are presented in other answers, but none of them change the fundamental operation: you must read in the existing file and then write down the data that you want to add, followed by existing data that you are reading.

Be sure to save the file descriptor file, but do not try to package this operation as few lines of code as possible. In fact, never look for the smallest lines of code - this is obfuscation, not programming.

+79
Dec 15 '10 at 20:24
source share

I would adhere to separate readings and letters, but we can certainly express more succinctly:

python2:

 with file('filename', 'r') as original: data = original.read() with file('filename', 'w') as modified: modified.write("new first line\n" + data) 

Python3:

 with open('filename', 'r') as original: data = original.read() with open('filename', 'w') as modified: modified.write("new first line\n" + data) 

Note: the file () function is not available in python3.

+53
Dec 15 '10 at 20:35
source share

Another approach:

 with open("infile") as f1: with open("outfile", "w") as f2: f2.write("#test firstline") for line in f1: f2.write(line) 

or one liner:

 open("outfile", "w").write("#test firstline\n" + open("infile").read()) 

Thanks for the opportunity to think about this problem :)

Greetings

+21
Dec 15 '10 at 20:18
source share
 with open("file", "r+") as f: s = f.read(); f.seek(0); f.write("prepend\n" + s) 
+9
Dec 15 '10 at 20:20
source share

You can save one record call as follows:

 f.write('#testfirstline\n' + temp) 

When using 'r +' you will have to rewind the file after reading and before writing.

+3
Dec 15 '10 at 20:04
source share

There are 3 liners, which I think is clear and flexible. It uses the list.insert function, so if you really want to add to the file, use l.insert (0, 'insert_str'). When I actually did this for the Python module I am developing, I used l.insert (1, 'insert_str') because I wanted to skip the line '# -coding: utf-8-' at line 0. Here is the code .

 f = open(file_path, 'r'); s = f.read(); f.close() l = s.splitlines(); l.insert(0, 'insert_str'); s = '\n'.join(l) f = open(file_path, 'w'); f.write(s); f.close() 
+3
Jan 04 '14 at 15:50
source share

The shortest way to do this while maintaining readability:

 with open('filename', 'rw') as testfile: testfile.writelines(['first line'] + testfile.readlines()) 
+2
Dec 15 '10 at 20:21
source share

Performs a task without reading the entire file in memory, although this may not work on Windows

 def prepend_line(path, line): with open(path, 'r') as old: os.unlink(path) with open(path, 'w') as new: new.write(str(line) + "\n") shutil.copyfileobj(old, new) 
+2
Jun 01 2018-12-12T00:
source share

One of the following functions is possible:

 import os open('tempfile', 'w').write('#testfirstline\n' + open('filename', 'r').read()) os.rename('tempfile', 'filename') 
0
Dec 15 '10 at 20:18
source share

If you want to add to the file after certain text, you can use the function below.

 def prepend_text(file, text, after=None): ''' Prepend file with given raw text ''' f_read = open(file, 'r') buff = f_read.read() f_read.close() f_write = open(file, 'w') inject_pos = 0 if after: pattern = after inject_pos = buff.find(pattern)+len(pattern) f_write.write(buff[:inject_pos] + text + buff[inject_pos:]) f_write.close() 

So, first you open the file, read it and save in one line. Then we try to find the character number in the line where the injection will take place. Then, with a single record and some clever line indexing, we can rewrite the entire file, including the entered text.

0
Aug 27 '15 at 13:55
source share

Can't I see something or can't we just use a buffer large enough to read the input file in parts (instead of all the contents) and with this buffer go through the file while it is open and continue to exchange the file <-> the contents of the buffer ?

This seems much more efficient (especially for large files) than reading all the contents in memory, changing it in memory, and writing back to the same file or (even worse) to another. Sorry, I don’t have time to implement the example fragment, I will come back to this later, but perhaps you understood the idea.

0
Jun 14 '19 at 7:33
source share



All Articles