29

I want to insert text at the top of an already existing file. How can I achieve this. I tried echo and tee but was not successful.

I was trying to insert repo line at the top of sources.list file from terminal.

Note

I need an one line quick solution, because another answer's method was known to me already

9
  • 1
    tee adds a line at the bottom of the file e.g. echo "deb http://extras.ubuntu.com/ubuntu precise main" | sudo tee -a /etc/apt/sources.list -- you also need sudo before tee to get admin privileges. But why on earth would you want to add something on the very top of sources.list? Jun 16 '12 at 11:30
  • 2
    @medigeek: somewhere in the OP's question history you'll find something about installing/updating from a CD-repo...I suspect that may be the reason...
    – ish
    Jun 16 '12 at 11:40
  • Thank @izx, Your assumption is correct. I'm quiet impressed. Can you also answer that question. That was about installing from a local repo using software-center and also setting my local repo for highest priority without placing it at the top. Thanks again.
    – Anwar
    Jun 16 '12 at 12:49
  • 1
    @izx, Here is the link about setting highest priority to my local repository. I will be glad if you can also check this question about software center. Thanks again for your first comment. was very glad.
    – Anwar
    Jun 16 '12 at 13:48
  • 1
    @medigeek, you can see this question for the explanation of such an uncommon question.
    – Anwar
    Jun 16 '12 at 13:56
43

It's actually quite easy with sed:

  • sed -i -e '1iHere is my new top line\' filename

  • 1i tells sed to insert the text that follows at line 1 of the file; don't forget the \ newline at the end so that the existing line 1 is moved to line 2.

6
  • 1
    Thanks. Just for the note: if you want to replace, instead of inserting use s instead of i in 1i.
    – Anwar
    Feb 2 '13 at 8:07
  • 4
    Sadly this fails for the empty file (it has no fist line, so sed never inserts).
    – Tino
    May 7 '14 at 1:44
  • @Tino For empty files you can just use echo "Text Here" >> Filename
    – Flotolk
    Aug 26 '18 at 20:17
  • doesn't work on MacOS 10
    – Krishna
    Jul 9 '19 at 7:44
  • Just want to add that on Ubuntu 20.04 the '\' newline gets output to the file, it is not needed (at first I had to escape the '\' in my text editor, but later removed the '\' and it seems to insert a newline fine. Jul 28 '20 at 8:09
8

In general editing in place with a script is tricky, but you can use echo and cat and then mv

echo "fred" > fred.txt
cat fred.txt t.txt >new.t.txt
# now the file new.t.txt has a new line "fred" at the top of it
cat new.t.txt
# can now do the rename/move
mv new.t.txt t.txt

However if you're playing with sources.list you need to add in some validation and bullet-proofing to detect errors etc because you really don't want to loose this. But that's a separate question :-)

3
  • I can do that already. I need a one line solution as izx gave. however thanks for your answer.
    – Anwar
    Jun 16 '12 at 12:52
  • 1
    @AnwarShah - ah sorry! You should have said that in your question :-)
    – Sean
    Jun 16 '12 at 12:56
  • I admit, +1 for your answer and also for comment. (I can't give more)
    – Anwar
    Jun 16 '12 at 13:57
6
./prepend.sh "myString" ./myfile.txt

known that prepend is my custom shell:

#!/bin/sh
#add Line at the top of File
# @author Abdennour TOUMI
if [ -e $2 ]; then
    sed -i -e '1i$1\' $2
fi

Use also a relatif path or absolute path , it should work fine :

./prepend.sh "my New Line at Top"  ../Documents/myfile.txt

Update :

if you want a permanent script for this , open nano /etc/bash.bashrc then add this function at the end of file:

function prepend(){
# @author Abdennour TOUMI
if [ -e $2 ]; then
    sed -i -e '1i$1\' $2
fi

}

Reopen you terminal and enjoy :

prepend "another line at top" /path/to/my/file.txt
0
5

And why not use a genuine text editor for that? ed is the standard text editor.

ed -s filename <<< $'1i\nFIRST LINE HERE\n.\nwq'

Or, if you want the commands to be more readable:

ed -s filename < <(printf '%s\n' 1i "FIRST LINE" . wq)
  • 1: go to firstline
  • i: insert mode
  • your stuff you want to insert...
  • .: stop inserting, go back to normal mode
  • wq: write and quit, thank you, good bye.
2
  • How to use shell variables substitution(in the FIRST LINE) with this?
    – vp_arth
    Feb 2 '15 at 8:08
  • 1
    @vp_arth If your content is in variable first_line then: ed -s filename < <(printf '%s\n' 1i "$first_line" . wq). Make sure that the variable doesn't expand to a single dot, and doesn't contain any newline characters (so sanitize it if it comes from user input). Feb 2 '15 at 13:25
3

You can use Vim in Ex mode:

ex -s -c '1i|hello world' -c -x sources.list
  1. 1 select 1st line

  2. i insert new line of text

  3. x save and close

1
  • 1
    Much simpler than other solutions provided so far. Thank you. Jul 10 '18 at 12:30
2

There is always the awk option. Replace string variable with your contents. This is not an in-place change though. Personally, I tend to not make in-place changes. This is definitely a personal preference. Two things, -v signifies a variable in awk and variable n is used here to match a line number, effectively NR == 1. You could use this in any number of ways just by changing the value of n and s.

string="My New first line"; awk -v n=1 -v s="$string" 'NR == n {print s} {print}'     file.source > file.target

Example:

% cat file.source                                                                                                                                      

First Line
Second Line
Third Line

% string="Updated First Line"; awk -v n=1 -v s="$string" 'NR == n {print s} {print}' file.source > file.target; cat ./file.target                      !698

Updated First Line
First Line
Second Line
Third Line
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.