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.