Illusionist
Illusionist

Reputation: 5509

Prepend line to beginning of a file

I can do this using a separate file, but how do I append a line to the beginning of a file?

f=open('log.txt','a')
f.seek(0) #get to the first position
f.write("text")
f.close()

This starts writing from the end of the file since the file is opened in append mode.

Upvotes: 111

Views: 204821

Answers (13)

Laurent
Laurent

Reputation: 1

As i came to the same problem with a+, moreover i wanted to insert a txt at any line. With all answers above i created a function to do this

def regelinvoeg(filename, insertnr, 
inserttxt):
   with open(filename, 'r+') as fp: 
      lines = fp.readlines() 
      lines.insert(insertnr, inserttxt)
      fp.seek(0) 
      fp.writelines(lines)


#create file with 2 lines. 
file = open("newfile.txt", "w")
file.write("This has been written to a 
file\n")
file.close()
file = open("newfile.txt", "a+")
file.write ("Voeg toe aan bestandje\n")
file.close()

#Ask for new to insert line
tekstinvoer = input("Write a textline to 
insert:\n")
regelnr = int(input("Give linenumber to 
insert\n"))

#use function to insert new textline on 
line two
regelinvoeg ("newfile.txt", regelnr-1, 
tekstinvoer+"\n") #subtract 1 from 
linenumber as list start with 0

#Print result
file = open("newfile.txt", "r")
print(file.read())
file.close()

Upvotes: 0

owengall
owengall

Reputation: 463

I believe (assuming you want to handle files too big to fit entire contents in memory) it would be easier to write in append mode (write order ascending), and have client/subscriber programs read using the file-read-backwards library.

In other words, simulate the file being prepended by the writer by reading the file lines in reverse order. This is my preferred solution since I don’t need the file to be stored in reverse order; I just want to be able to quickly access the newest line when reading it subsequently.

Upvotes: 0

jeffpkamp
jeffpkamp

Reputation: 2866

To put code to NPE's answer, I think the most efficient way to do this is:

def insert(originalfile,string):
    with open(originalfile,'r') as f:
        with open('newfile.txt','w') as f2: 
            f2.write(string)
            f2.write(f.read())
    os.remove(originalfile)
    os.rename('newfile.txt',originalfile)

Upvotes: 18

Hussain Thameezdeen
Hussain Thameezdeen

Reputation: 11

I tried a different approach:

I wrote first line into a header.csv file. body.csv was the second file. Used Windows type command to concatenate them one by one into final.csv.

import os

os.system('type c:\\\header.csv c:\\\body.csv > c:\\\final.csv')

Upvotes: 0

JD Solanki
JD Solanki

Reputation: 998

An improvement over the existing solution provided by @eyquem is as below:

def prepend_text(filename: Union[str, Path], text: str):
    with fileinput.input(filename, inplace=True) as file:
        for line in file:
            if file.isfirstline():
                print(text)
            print(line, end="")

It is typed, neat, more readable, and uses some improvements python got in recent years like context managers :)

Upvotes: 0

Gilad Deutsch
Gilad Deutsch

Reputation: 415

If the file is the too big to use as a list, and you simply want to reverse the file, you can initially write the file in reversed order and then read one line at the time from the file's end (and write it to another file) with file-read-backwards module

Upvotes: 1

Gopi Srikanth
Gopi Srikanth

Reputation: 23

with open("fruits.txt", "r+") as file:
    file.write("bab111y")
    file.seek(0)
    content = file.read()
    print(content)

Upvotes: -1

Joonho Park
Joonho Park

Reputation: 563

The clear way to do this is as follows if you do not mind writing the file again

with open("a.txt", 'r+') as fp:
    lines = fp.readlines()     # lines is list of line, each element '...\n'
    lines.insert(0, one_line)  # you can use any index if you know the line index
    fp.seek(0)                 # file pointer locates at the beginning to write the whole file again
    fp.writelines(lines)       # write whole lists again to the same file

Note that this is not in-place replacement. It's writing a file again.

In summary, you read a file and save it to a list and modify the list and write the list again to a new file with the same filename.

Upvotes: 12

lloyd
lloyd

Reputation: 139

Different Idea:

(1) You save the original file as a variable.

(2) You overwrite the original file with new information.

(3) You append the original file in the data below the new information.

Code:

with open(<filename>,'r') as contents:
      save = contents.read()
with open(<filename>,'w') as contents:
      contents.write(< New Information >)
with open(<filename>,'a') as contents:
      contents.write(save)

Upvotes: 13

Kevin Mbugua
Kevin Mbugua

Reputation: 375

num = [1, 2, 3] #List containing Integers

with open("ex3.txt", 'r+') as file:
    readcontent = file.read()  # store the read value of exe.txt into 
                                # readcontent 
    file.seek(0, 0) #Takes the cursor to top line
    for i in num:         # writing content of list One by One.
        file.write(str(i) + "\n") #convert int to str since write() deals 
                                   # with str
    file.write(readcontent) #after content of string are written, I return 
                             #back content that were in the file

Upvotes: 5

eyquem
eyquem

Reputation: 27585

In modes 'a' or 'a+', any writing is done at the end of the file, even if at the current moment when the write() function is triggered the file's pointer is not at the end of the file: the pointer is moved to the end of file before any writing. You can do what you want in two manners.

1st way, can be used if there are no issues to load the file into memory:

def line_prepender(filename, line):
    with open(filename, 'r+') as f:
        content = f.read()
        f.seek(0, 0)
        f.write(line.rstrip('\r\n') + '\n' + content)

2nd way:

def line_pre_adder(filename, line_to_prepend):
    f = fileinput.input(filename, inplace=1)
    for xline in f:
        if f.isfirstline():
            print line_to_prepend.rstrip('\r\n') + '\n' + xline,
        else:
            print xline,

I don't know how this method works under the hood and if it can be employed on big big file. The argument 1 passed to input is what allows to rewrite a line in place; the following lines must be moved forwards or backwards in order that the inplace operation takes place, but I don't know the mechanism

Upvotes: 152

NPE
NPE

Reputation: 500953

In all filesystems that I am familiar with, you can't do this in-place. You have to use an auxiliary file (which you can then rename to take the name of the original file).

Upvotes: 21

Mark Ransom
Mark Ransom

Reputation: 308538

There's no way to do this with any built-in functions, because it would be terribly inefficient. You'd need to shift the existing contents of the file down each time you add a line at the front.

There's a Unix/Linux utility tail which can read from the end of a file. Perhaps you can find that useful in your application.

Upvotes: 4

Related Questions