Take the 2-minute tour ×

This is probably a complex solution.

I am looking for a simple operator like ">>", but for prepending.

I am afraid it does not exist. I'll have to do something like

 mv myfile tmp
 cat myheader tmp > myfile

Anything smarter? (I am not fond of tmp files)

share|improve this question
add comment

26 Answers

up vote 10 down vote accepted

This little hack was a quick off-the-cuff answer. However, this question has turned out strangely popular over the years and the solution hasn't stood the test of time. Use at your own peril...

text="Hello world
What's up?"

exec 3<> yourfile && awk -v TEXT="$text" 'BEGIN {print TEXT}{print}' yourfile >&3

Creating another file descriptor for the file (exec 3<> yourfile) thence writing to that (>&3) seems to overcome the read/write on same file dilemma. Works for me on 600K files with awk. However trying the same trick using 'cat' fails.

Passing the prependage as a variable to awk (-v TEXT="$text") overcomes the literal quotes nuisance that hinders 'sed'.

share|improve this answer
WARNING: check the output to make sure nothing has changed but the first line. I used this solution, and although it seemed to work, I noticed that some new lines seemed to be added. I don't understand where these came from, so I cannot be sure that this solution really has a problem, but beware. –  conradlee Mar 18 '10 at 15:58
Note in the bash example above that the double quotes span over the carriage return in order to demonstrate prepending multiple lines. Check your shell and text editor are being cooperative. \r\n comes to mind. –  John Mee Mar 19 '10 at 5:05
Use this with caution! See the following comment for why: stackoverflow.com/questions/54365/… –  atc Dec 30 '10 at 13:45
If it's now unreliable, how about updating your answer with a better solution? –  yourfriendzak Oct 25 '13 at 2:50
add comment

This still uses a temp file, but at least it is on one line:

echo "text" | cat - yourfile > /tmp/out && mv /tmp/out yourfile

Credit: BASH: Prepend A Text / Lines To a File

share|improve this answer
add comment
echo '0a
your text here
w' | ed some_file

ed is the Standard Editor! http://www.gnu.org/fun/jokes/ed.msg.html

share|improve this answer
or, instead of hardcoding the text to be inserted: 0r header.file –  glenn jackman Apr 8 '11 at 10:57
add comment

John Mee: your method is not guaranteed to work, and will probably fail if you prepend more than 4096 byte of stuff (at least that's what happens with gnu awk, but I suppose other implementations will have similar constraints). Not only will it fail in that case, but it will enter an endless loop where it will read its own output, thereby making the file grow until all the available space is filled.

Try it for yourself:

exec 3<>myfile && awk 'BEGIN{for(i=1;i<=1100;i++)print i}{print}' myfile >&3

(warning: kill it after a while or it will fill the filesystem)

Moreover, it's very dangerous to edit files that way, and it's very bad advice, as if something happens while the file is being edited (crash, disk full) you're almost guaranteed to be left with the file in an inconsistent state.

share|improve this answer
This should probably be a comment, not a separate answer. –  lkraav Aug 13 '11 at 9:50
@Ikraav: maybe, but the "comment" is very long and elaborate (and useful), it will not look good and perhaps doesn't fit with StackOverflow's limited comment capacity anyway. –  Hendy Irawan Oct 17 '11 at 9:45
add comment

The workaround to the overwrite problem is using tee:

cat header main | tee main > /dev/null
share|improve this answer
This seems not to work for long files. –  Justin L. Jun 7 '12 at 17:47
add comment

It may be worth noting that it often is a good idea to safely generate the temporary file using a utility like mktemp, at least if the script will ever be executed with root privileges. You could for example do the following (again in bash):

(tmpfile=`mktemp` && { echo "prepended text" | cat - yourfile > $tmpfile && mv $tmpfile yourfile; } )
share|improve this answer
add comment

Not possible without a temp file, but here goes a oneliner

{ echo foo; cat oldfile; } > newfile && mv newfile oldfile

You can use other tools such as ed or perl to do it without temp files.

share|improve this answer
add comment

assuming that the file you want to edit is my.txt

$cat my.txt    
this is the regular file

And the file you want to prepend is header

$ cat header
this is the header

Be sure to have a final blank line in the header file.
Now you can prepend it with

$cat header <(cat my.txt) > my.txt

You end up with

$ cat my.txt
this is the header
this is the regular file

As far as I know this only works in 'bash'.

share|improve this answer
why does this work? Do the parentheses cause the middle cat to execute in a separate shell and dump the entire file at once? –  Catskul Oct 26 '10 at 19:06
I think the <(cat my.txt) creates a temporary file somewhere in the file system. This file is then read before the original file is modified. –  cb0 Nov 9 '10 at 15:08
Someone once showed me what you can do with the "<( )" syntax. However I've never learned how this methode is called neither could I find something in the bash manpage. If someone knows more about it please let me know. –  cb0 Nov 9 '10 at 15:11
man bash | less '+/Process Substitution' –  glenn jackman Apr 8 '11 at 10:51
add comment

When you start trying to do things that become difficult in shell-script, I would strongly suggest looking into rewriting the script in a "proper" scripting language (Python/Perl/Ruby/etc)

As for prepending a line to a file, it's not possible to do this via piping, as when you do anything like cat blah.txt | grep something > blah.txt, it inadvertently blanks the file. There is a small utility command called sponge you can install (you do cat blah.txt | grep something | sponge blah.txt and it buffers the contents of the file, then writes it to the file). It is similar to a temp file but you dont have to do that explicitly. but I would say that's a "worse" requirement than, say, Perl.

There may be a way to do it via awk, or similar, but if you have to use shell-script, I think a temp file is by far the easiest(/only?) way..

share|improve this answer
+1 for recommending a proper scripting language. –  Olivier 'Ölbaum' Scherler Apr 26 '13 at 8:38
add comment

If you need this on computers you control, install the package "moreutils" and use "sponge". Then you can do:

cat header myfile | sponge myfile
share|improve this answer
add comment

Like Daniel Velkov suggests, use tee.
To me, that's simple smart solution:

{ echo foo; cat bar; } | tee bar > /dev/null
share|improve this answer
add comment

A variant on cb0's solution for "no temp file" to prepend fixed text:

echo "text to prepend" | cat - file_to_be_modified | ( cat > file_to_be_modified ) 

Again this relies on sub-shell execution - the (..) - to avoid the cat refusing to have the same file for input and output.

Note: Liked this solution. However, in my Mac the original file is lost (thought it shouldn't but it does). That could be fixed by writing your solution as: echo "text to prepend" | cat - file_to_be_modified | cat > tmp_file; mv tmp_file file_to_be_modified

share|improve this answer
I too find the original file lost. Ubuntu Lucid. –  Hedgehog Feb 6 '12 at 3:36
The solution of @nemisj seems to work. –  Hedgehog Feb 6 '12 at 3:46
add comment

WARNING: this needs a bit more work to meet the OP's needs.

There should be a way to make the sed approach by @shixilun work despite his misgivings. There must be a bash command to escape whitespace when reading a file into a sed substitute string (e.g. replace newline characters with '\n'. Shell commands vis and cat can deal with nonprintable characters, but not whitespace, so this won't solve the OP's problem:

sed -i -e "1s/^/$(cat file_with_header.txt)/" file_to_be_prepended.txt

fails due to the raw newlines in the substitute script, which need to be prepended with a line continuation character () and perhaps followed by an &, to keep the shell and sed happy, like this SO answer

sed has a size limit of 40K for non-global search-replace commands (no trailing /g after the pattern) so would likely avoid the scary buffer overrun problems of awk that anonymous warned of.

share|improve this answer
add comment

Why not simply use the ed command (as already suggested by fluffle here)?

ed reads the whole file into memory and automatically performs an in-place file edit!

So, if your file is not that huge ...

# cf. "Editing files with the ed text editor from scripts.",
# http://wiki.bash-hackers.org/doku.php?id=howto:edit-ed

prepend() {
   printf '%s\n' H 1i "${1}" . wq | ed -s "${2}"

echo 'Hello, world!' > myfile
prepend 'line to prepend' myfile

Yet another workaround would be using open file handles as suggested by Jürgen Hötzel in Redirect output from sed 's/c/d/' myFile to myFile

echo cat > manipulate.txt
exec 3<manipulate.txt
# Prevent open file from being truncated:
rm manipulate.txt
sed 's/cat/dog/' <&3 > manipulate.txt

All this could be put on a single line, of course.

share|improve this answer
add comment

The one which I use. This one allows you to specify order, extra chars, etc in the way you like it:

echo -e "TEXTFIRSt\n$(< header)\n$(< my.txt)" > my.txt

P.S: only it's not working if files contains text with backslash, cause it gets interpreted as escape characters

share|improve this answer
add comment
sed -i -e '1rmyheader' -e '1{h;d}' -e '2{x;G}' myfile
share|improve this answer
add comment

Mostly for fun/shell golf, but

ex -c '0r myheader|x' myfile

will do the trick, and there are no pipelines or redirections. Of course, vi/ex isn't really for noninteractive use, so vi will flash up briefly.

share|improve this answer
add comment

Bah! No one cared to mention about tac.

endor@grid ~ $ tac --help
Usage: tac [OPTION]... [FILE]...
Write each FILE to standard output, last line first.

Mandatory arguments to long options are mandatory for short options too.
      --help     display this help and exit
      --version  output version information and exit

Report tac bugs to bug-coreutils@gnu.org
Report tac translation bugs to <http://translationproject.org/team/>
share|improve this answer
tac could solve the problem, but you just printed out the help for tac... Not particularly useful. –  Catskul Oct 26 '10 at 18:54
not extremely helpful here -- it would be: { tac myfile; tac header; } | tac > newfile && mv newfile myfile –  glenn jackman Apr 8 '11 at 11:00
add comment
current=`cat my_file` && echo 'my_string' > my_file && echo $current >> my_file

where "my_file" is the file to prepend "my_string" to.

share|improve this answer
add comment

I'm liking @fluffle's ed approach the best. After all, any tool's command line switches vs scripted editor commands are essentially the same thing here; not seeing a scripted editor solution "cleanliness" being any lesser or whatnot.

Here's my one-liner appended to .git/hooks/prepare-commit-msg to prepend an in-repo .gitmessage file to commit messages:

echo -e "1r $PWD/.gitmessage\n.\nw" | ed -s "$1"

Example .gitmessage:

# Commit message formatting samples:
#       runlevels: boot +consolekit -zfs-fuse

I'm doing 1r instead of 0r, because that will leave the empty ready-to-write line on top of the file from the original template. Don't put an empty line on top of your .gitmessage then, you will end up with two empty lines. -s suppresses diagnostic info output of ed.

In connection with going through this, I discovered that for vim-buffs it is also good to have:

        editor = vim -c ':normal gg'
share|improve this answer
add comment

variables, ftw?

NEWFILE=$(echo deb http://mirror.csesoc.unsw.edu.au/ubuntu/ $(lsb_release -cs) main universe restricted multiverse && cat /etc/apt/sources.list)
echo "$NEWFILE" | sudo tee /etc/apt/sources.list
share|improve this answer
add comment

Here's what I discovered:

echo -e "header \n$(cat file)" >file
share|improve this answer
This is the same as the earlier suggestion by @nemisj No? –  Hedgehog Feb 6 '12 at 3:44
add comment

I think this is the cleanest variation of ed:

cat myheader | { echo '0a'; cat ; echo -e ".\nw";} | ed myfile

as a function:

function prepend() { { echo '0a'; cat ; echo -e ".\nw";} | ed $1; }

cat myheader | prepend myfile
share|improve this answer
add comment
sed -i -e "1s/^/new first line\n/" old_file.txt
share|improve this answer
Oops...that only prepends one line...not an arbitrary file... –  shixilun Sep 30 '10 at 22:39
add comment

If you're scripting in BASH, actually, you can just issue:

cat - yourfile  /tmp/out && mv /tmp/out yourfile

That's actually in the Complex Example you yourself posted in your own question.

share|improve this answer
An editor suggested changing this to cat - yourfile <<<"text" > /tmp/out && mv /tmp/out yourfile, however that's sufficiently different from my answer that it should be it's own answer. –  Tim Kennedy Jul 19 '13 at 13:38
add comment

With $( command ) you can write the output of a command into a variable. So I did it in three commands in one line and no temp file.

originalContent=$(cat targetfile) && echo "text to prepend" > targetfile && echo "$originalContent" >> targetfile
share|improve this answer
add comment

Your Answer


