Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shell one liner to prepend to a file

Tags:

shell

unix

People also ask

How do you prepend in bash?

As far as I know there is no prepend operator on a bash or any other shell, however there are many ways to do the same. You can use ed, sed, perl, awk and so on to add text to the beginning of a file in Bash under Linux or Unix-like systems.

How do you prepend text in Linux?

1s;^;to be prepended; substitutes the beginning of the first line by the given replacement string, using ; as a command delimiter.

How do you write a line to a file in shell script?

Using '>>' with 'echo' command appends a line to a file. Another way is to use 'echo,' pipe(|), and 'tee' commands to add content to a file.

How do I append a line to an existing file in Linux?

Append Text Using >> Operator The >> operator redirects output to a file, if the file doesn't exist, it is created but if it exists, the output will be appended at the end of the file. For example, you can use the echo command to append the text to the end of the file as shown.


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


echo '0a
your text here
.
w' | ed some_file

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


The hack below was a quick off-the-cuff answer which worked and received lots of upvotes. Then, as the question became more popular and more time passed, outraged people started reporting that it sorta worked but weird things could happen, or it just didn't work at all, so it was furiously downvoted for a time. Such fun.

The solution exploits the exact implementation of file descriptors on your system and, because implementation varies significantly between nixes, it's success is entirely system dependent, definitively non-portable, and should not be relied upon for anything even vaguely important.

Now, with all that out of the way the answer was:


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 problem which prevents doing this trick with 'sed'.

#!/bin/bash
text="Hello world
What's up?"

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

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.


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.


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

cat header myfile | sponge myfile

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; } )