Prepend line to beginning of a file
Asked Answered
T

13

109

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.

Tommyetommyrot answered 6/5, 2011 at 16:56 Comment(2)
possible duplicate of Python f.write() at beginning of file?Croft
No, it's not solution in that link cant be used for append file, it will keep on last line.Incommunicable
A
150

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

Animadvert answered 6/5, 2011 at 21:52 Comment(4)
with open(filename,'r+') as f: will close the file?Nickerson
@TomBrito Yes, the new with statement allows you avoid common try/except/finally boilerplate code. It was added in Python version 2.5.Evaporation
1st way removes the first line.Wadleigh
@Wadleigh Is that true for the latest answer? I don't see that behavior with the first method.Gley
A
20

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).

Ajax answered 6/5, 2011 at 16:57 Comment(0)
D
18

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)
Deontology answered 18/2, 2017 at 6:9 Comment(3)
Disastrous! Copying all the file into a new one with the line.Masturbate
@TonyTannous if you've got a way to do it without, please do share. I know a lot of people would be interested.Deontology
added for Win OS... os.remove(originalfile)Selfdenial
E
13

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)
Eager answered 29/3, 2018 at 2:8 Comment(2)
^^^ This is gold ^^^Plagioclase
No need to open the file a second time in a mode, you can just do two writes in the same with open block.Blearyeyed
I
12

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.

Insensate answered 21/1, 2019 at 2:0 Comment(0)
C
5
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
Colleen answered 7/2, 2018 at 10:16 Comment(0)
P
4

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.

Preterit answered 6/5, 2011 at 17:8 Comment(0)
E
1

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

Echols answered 4/1, 2020 at 13:36 Comment(1)
I didn’t see this answer before, but it’s the same as mine. If I get the chance I’ll update this one to merge them with combined details.Pede
S
0

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 :)

Salacious answered 5/1, 2022 at 10:17 Comment(0)
B
0

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')
Batangas answered 15/4, 2022 at 10:9 Comment(0)
P
0

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.

Pede answered 13/8, 2023 at 14:34 Comment(0)
S
0

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()
Shoreward answered 28/10, 2023 at 12:9 Comment(0)
S
-1
with open("fruits.txt", "r+") as file:
    file.write("bab111y")
    file.seek(0)
    content = file.read()
    print(content)
Sneaky answered 2/11, 2019 at 15:27 Comment(2)
This is not correct. Instead of appending to the start of the file, the first 7 characters of the file will be REPLACED with "bab111y".Lunik
It can be useful if you know, or you can estimate the size of what to you want to write at the beginning. One can simply leave enough space to do it... Maybe just need to be completed to explain this fact.Schuck

© 2022 - 2024 — McMap. All rights reserved.