Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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

share|improve this question

7 Answers 7

up vote 88 down vote accepted
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
share|improve this answer
1  
the first one works great! would you mind explaining the logic? im not particularly sure how to interpret the syntax. –  user479534 Feb 18 '11 at 4:24
8  
@user8347: Pipe (|) the message (echo '...') to cat which uses - (standard input) as the first file and todo.txt as the second. cat conCATenates multiple files. Send the output (>) to a file named temp. If there are no errors (&&) from cat then rename (mv) the temp file back to the original file (todo.txt). –  Dennis Williamson Feb 18 '11 at 4:51
    
cat could be a problem if cat encounters \n –  itaifrenkel Jan 26 at 8:50
    
@itaifrenkel: In what way? –  Dennis Williamson Jan 26 at 12:16
    
Instead of printing \n it may print a newline. Happened to me. Used the sed version just fine instead –  itaifrenkel Jan 26 at 21:37

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 the file 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' && cat todo.txt) > todo.txt
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.

share|improve this answer
    
Agreed, this is great! –  Emanuel Berg Jan 12 '13 at 4:27
1  
I don't get $(...) executed at all. –  SCL Feb 22 '13 at 17:10
2  
That might work better (or at all) with double quotes instead of single… –  ℝaphink May 22 '13 at 7:25
2  
Won't the -e also convert escape sequences inside todo.txt? –  Mk12 Sep 2 '13 at 21:23

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.

share|improve this answer

If the text file is small enough to fit in memory, you don't have to create a temporary file to replace it with. You can load it all into memory and write it back out to the file.

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

It's impossible to add lines to the beginning of the file without over writing the whole file.

share|improve this answer
    
Just to ask the obvious question: Where's the character limit of shell variables? –  nixda Jan 9 '13 at 22:59
    
As far as I'm aware, it's only limited by the amount of memory available. I've filled up variables well over 100MB into memory. text=$(cat file). Be careful to only use text though, because shell variables aren't binary clean mywiki.wooledge.org/BashFAQ/058 –  Rucent88 Jan 14 '13 at 1:48

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.

share|improve this answer
1  
Say you're out of disk space so that new_todo.txt gets written only partially. Your solution appears to lose the original file. –  NPE Feb 17 '11 at 10:31
    
Who runs out of disk space? ;-) It's just a simple example. –  Keith Feb 17 '11 at 10:33
    
@Keith Someone working on a VM who didn't expect to need a particularly large virtual drive. Or someone moving a large file. In any case, the real argument against this is directory permissions; if you don't have permission to create new files in the given directory, the only command that will successfully execute in your script is the rm of the original file. –  Parthian Shot Jul 1 at 20:23

You cannot insert content at the beginning of a file. The only thing you can do is either replace existing content or append bytes after the current end of file.

Any solution to your question then requires a temporary file (or buffer) to be created (on memory or on disk) which will eventually overwrite the original file.

Beware not loosing data by preserving the original file while building the new one, should the file system happen to be full during the process. eg:

cat <(echo task go there) todo.txt > todo.txt.new && mv todo.txt.new todo.txt
share|improve this answer

You can use tee:

echo 'task goes here' | cat - todo.txt | tee todo.txt
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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