How do I add text to the beginning of a file in Bash?

Hi I want to prepend text to a file. For example I want to add tasks to the beginning of a todo.txt file. I am aware of echo 'task goes here' >> todo.txt but that adds the line to the end of the file (not what I want).


Linux :

echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt

or

sed -i '1s/^/task goes here\n/' todo.txt

or

sed -i '1itask goes here' todo.txt

Mac os x :

sed -i '.bak' '1s/^/task goes here\'$'\n/g' todo.txt

or

echo -e "task goes here\n$(cat todo.txt)" > todo.txt

or

echo 'task goes here' | cat - todo.txt > temp && mv temp todo.txt

A simpler option in my opinion is :

echo -e "task goes here\n$(cat todo.txt)" > todo.txt

This works because the command inside of $(...) is executed before todo.txt is overwritten with > todo.txt

While the other answers work fine, I find this much easier to remember because I use echo and cat every day.

EDIT: This solution is a very bad idea if there are any backslashes in todo.txt, because thanks to the -e flag echo will interpret them. Another, far easier way to get newlines into the preface string is...

echo "task goes here
$(cat todo.txt)" > todo.txt

...simply to use newlines. Sure, it isn't a one-liner anymore, but realistically it wasn't a one-liner before, either. If you're doing this inside a script, and are worried about indenting (e.g. you're executing this inside a function) there are a few workarounds to make this still fit nicely, including but not limited to:

echo 'task goes here'$'\n'"$(cat todo.txt)" > todo.txt

Also, if you care about whether a newline gets added to the end of todo.txt, don't use these. Well, except the second-to-last one. That doesn't mess with the end.


The moreutils have a nice tool called sponge:

echo "task goes here" | cat - todo.txt | sponge todo.txt

It'll "soak up" STDIN and then write to the file, which means you don't have to worry about temporary files and moving them around.

You can get moreutils with many Linux distros, through apt-get install moreutils, or on OS X using Homebrew, with brew install moreutils.


You can use the POSIX tool ex:

ex a.txt <<eof
1 insert
Sunday
.
xit
eof

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html


You can create a new, temporary file.

echo "new task" > new_todo.txt
cat todo.txt >> new_todo.txt
rm todo.txt
mv new_todo.txt todo.txt

You might also use sed or awk. But basically the same thing happens.