Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unix command to prepend text to a file

People also ask

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

Use sed 's insert ( i ) option which will insert the text in the preceding line. Also note that some non-GNU sed implementations (for example the one on macOS) require an argument for the -i flag (use -i '' to get the same effect as with GNU sed ).

How do you append a line at the beginning of a file in Unix?

If you want to add a line at the beginning of a file, you need to add \n at the end of the string in the best solution above. The best solution will add the string, but with the string, it will not add a line at the end of a file. On Mac OS, was getting error with "undefined label".

How do I add text to a file in Unix?

Type the cat command followed by the double output redirection symbol ( >> ) and the name of the file you want to add text to. A cursor will appear on the next line below the prompt. Start typing the text you want to add to the file.


printf '%s\n%s\n' "to be prepended" "$(cat text.txt)" >text.txt

sed -i.old '1s;^;to be prepended;' inFile
  • -i writes the change in place and take a backup if any extension is given. (In this case, .old)
  • 1s;^;to be prepended; substitutes the beginning of the first line by the given replacement string, using ; as a command delimiter.

Process Substitution

I'm surprised no one mentioned this.

cat <(echo "before") text.txt > newfile.txt

which is arguably more natural than the accepted answer (printing something and piping it into a substitution command is lexicographically counter-intuitive).

...and hijacking what ryan said above, with sponge you don't need a temporary file:

sudo apt-get install moreutils
<<(echo "to be prepended") < text.txt | sponge text.txt

EDIT: Looks like this doesn't work in Bourne Shell /bin/sh


Here String (zsh only)

Using a here-string - <<<, you can do:

<<< "to be prepended" < text.txt | sponge text.txt

This is one possibility:

(echo "to be prepended"; cat text.txt) > newfile.txt

you'll probably not easily get around an intermediate file.

Alternatives (can be cumbersome with shell escaping):

sed -i '0,/^/s//to be prepended/' text.txt

This will work to form the output. The - means standard input, which is provide via the pipe from echo.

echo -e "to be prepended \n another line" | cat - text.txt

To rewrite the file a temporary file is required as cannot pipe back into the input file.

echo "to be prepended" | cat - text.txt > text.txt.tmp
mv text.txt.tmp text.txt

If it's acceptable to replace the input file:

Note:

  • Doing so may have unexpected side effects, notably potentially replacing a symlink with a regular file, ending up with different permissions on the file, and changing the file's creation (birth) date.

  • sed -i, as in Prince John Wesley's answer, tries to at least restore the original permissions, but the other limitations apply as well.

Here's a simple alternative that uses a temporary file (it avoids reading the whole input file into memory the way that shime's solution does):

{ printf 'to be prepended'; cat text.txt; } > tmp.txt && mv tmp.txt text.txt

Using a group command ({ ...; ...; }) is slightly more efficient than using a subshell ((...; ...)), as in 0xC0000022L's solution.

The advantages are:

  • It's easy to control whether the new text should be directly prepended to the first line or whether it should be inserted as new line(s) (simply append \n to the printf argument).

  • Unlike the sed solution, it works if the input file is empty (0 bytes).


The sed solution can be simplified if the intent is to prepend one or more whole lines to the existing content (assuming the input file is non-empty):

sed's i function inserts whole lines:

With GNU sed:

# Prepends 'to be prepended' *followed by a newline*, i.e. inserts a new line.
# To prepend multiple lines, use '\n' as part of the text.
# -i.old creates a backup of the input file with extension '.old'
sed -i.old '1 i\to be prepended' inFile

A portable variant that also works with macOS / BSD sed:

# Prepends 'to be prepended' *followed by a newline*
# To prepend multiple lines, escape the ends of intermediate
# lines with '\'
sed -i.old -e '1 i\
to be prepended' inFile

Note that the literal newline after the \ is required.


If the input file must be edited in place (preserving its inode with all its attributes):

Using the venerable ed POSIX utility:

Note:

  • ed invariably reads the input file as a whole into memory first.

To prepend directly to the first line (as with sed, this won't work if the input file is completely empty (0 bytes)):

ed -s text.txt <<EOF
1 s/^/to be prepended/
w
EOF
  • -s suppressed ed's status messages.
  • Note how the commands are provided to ed as a multi-line here-document (<<EOF\n...\nEOF), i.e., via stdin; by default string expansion is performed in such documents (shell variables are interpolated); quote the opening delimiter to suppress that (e.g., <<'EOF').
  • 1 makes the 1st line the current line
  • function s performs a regex-based string substitution on the current line, as in sed; you may include literal newlines in the substitution text, but they must be \-escaped.
  • w writes the result back to the input file (for testing, replace w with ,p to only print the result, without modifying the input file).

To prepend one or more whole lines:

As with sed, the i function invariably adds a trailing newline to the text to be inserted.

ed -s text.txt <<EOF
0 i
line 1
line 2
.
w
EOF
  • 0 i makes 0 (the beginning of the file) the current line and starts insert mode (i); note that line numbers are otherwise 1-based.
  • The following lines are the text to insert before the current line, terminated with . on its own line.