BASH: Prepend A Text / Lines To a File

Posted on in Categories , , , , , , last updated November 2, 2016

I am a new Unix system user with a bash as a default shell. I can append text to a file using >> operator but how do I prepend a text to a file? I want the opposite operation of >>. How can I prepend some data to a text file?

Linux and Unix command to prepend text to a file

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.

Prepend a text using a temporary file

Here is simple solution using a temporary file to prepend text:

echo 'line 1' > /tmp/newfile
echo 'line 2' >> /tmp/newfile
cat yourfile >> /tmp/newfile
cp /tmp/newfile yourfile

Here is one line solution:

echo "text"|cat - yourfile > /tmp/out && mv /tmp/out yourfile

Using bash only solution

No need to create a temp file:

echo -e "DATA-Line-1\n$(cat input)" > input
cat input

To add multiple lines:

echo -e "DATA-Line-1\nDATA-Line-2\n$(cat input)" > input
cat input

Use sed command to prepend data to a text file

The syntax is:

sed  '1s;^;DATA-Line-1\n;' input > output
## OR ##
sed -i '1s;^;DATA-Line-1\n;' input
## verify it ##
cat input

Here is a sample input file:

$ cat input.txt
This is a test file.
I love Unix.

Next prepend two lines (make sure you add \n):

$ sed -i '1s;^;Force-1\nForce-2\n;' input.txt
$ cat input.txt
Force-1
Force-2
This is a test file.
I love Unix.

How do I prepend a string to the beginning of each line in a file?

The awk syntax is:

awk '{print "Line-1" $0}' file

The sed syntax is:

sed -i -e 's/^/Line-1/' file

Examples

Here is our sample file:

$ cat data.txt
Maybe I'm crazy
Maybe you're crazy
Maybe we're crazy
Probably

Use the sed or awk as follows:

$ sed -i -e 's/^/DATA-Here/' data.txt
$ cat data.txt
DATA-HereMaybe I'm crazy
DATA-HereMaybe you're crazy
DATA-HereMaybe we're crazy
DATA-HereProbably

See sed,awk, and bash command man pages for more info.

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on Twitter, Facebook, Google+.

41 comment

  1. perl -p -i -e ‘BEGIN { print “First line\n” }’ originalfile

    should work without needing an explicit temp file

    If you’re going to use these commands in a script, though, “man mktemp” first.

    Sean

      1. Works, but it _does_ use a temporary file behind the covers.
        The following is from the info document:
        >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        –in-place[=SUFFIX]’
        This option specifies that files are to be edited in-place. GNU
        `sed’ does this by creating a temporary file and sending output to
        this file rather than to the standard output.(1).
        <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

    1. That works on linux but not in solaris (unless you install gsed package), because de solaris sed command doesnt support “in place option” -i.

      In that case

      echo “text”|cat – yourfile > /tmp/out && mv /tmp/out yourfile

      works for me

      Thanks for help :)

      1. Yes it does. The `-i` option is a mandatory part of POSIX, so it will work on any UNIX that takes itself seriously, Solaris included.

        It just works differently, i.e. GNU sed allows you to omit the argument of the `-i` flag, as was done in the example, whereas most other seds require it.

        Try:

        sed -i.bak ‘1i Prepended line’ /tmp/newfile

        Now hang your head in shame.

  2. Thread’s old, I know, but I wanted to note that tac — at least in the version I have in Cygwin, is not fully “cat in reverse” alas.

    As you say, it’ll print from the end — but it won’t take an argument like this:

    tac >> somefilethatyouwanttoPREPENDtextto

    Just thought I’d note that for others who might be searching the same issue as the OP.
    This seems like such an obviously useful utility it’s unbelievable what a pita it is.

  3. I tried the perl command (same one suggested to me by someone on IRC) and it didn’t work. It just printed to stdout and left the file unchanged. I’m kind of surprised two different people suggested the exact same non-working command, so I must be doing something wrong. What could I be doing wrong though??

    I like the sed command, but I needed to add more than one line (and my text contained special characters).

    This worked for me:

    sed -i ‘1{h; r headerfile.txt
    D;}
    2{x; G; }
    ‘ filetoedit.txt

    I’m not even really sure how it works, I just combined bits of code from a couple of random scripts I saw elsewhere. I should learn more sed :-P

    this also worked:

    for FILE in `find . -iname “*.php”`
    do
    cat header.php | cat – $FILE > /tmp/mytmpfile && mv /tmp/mytmpfile $FILE
    done

  4. tac does not add a damn thing.
    Given this command:
    tac biglist.txt “thisistext” > biglist5.txt
    — I get the error
    tac: cannot open `thisistext’ for reading: No such file or directory.
    Considering it’s a close cousin of cat, I shouldn’t expect it to do any more, logically.
    Please do the newbie world a favour and remove any references to tac in this thread.

    BZT

    1. You need to put your prepend data into the file “thisistext”. Also, unless you want your file to come out upside down, you’ll have to pipe the output from the first tac into a second tac before redirecting to a file.

    2. With a little creative use of shell commands, you can avoid needing a second input file. Passing ‘-‘ as an argument tells most tools to use standard input or output (whichever applies) as a file.

      echo “my_prepend_text_goes_here” | tac biglist.txt – | tac > biglist5.txt

      There are a couple of tricks where you can avoid needing to create biglist5.txt in the process (storing results to a variable or using “tee” to write your output), but I can’t find anything that will work on large files.

  5. How about a command or script to add the same text to every line OF a file, not just to the file itself???

    Believe it or not
    bash prepend same text to beginning of all lines of file
    does not have an exact match on Google. Ask.com and Yahoo! were sloppy with it (read:inexact and wide of the mark ultimately). Just more proof to my assertion that the world is going stupid.

    BZT

  6. This perl one-liner will prefix (not prepend, which isn’t a word) a line to the beginning of a file.

    perl -pi -e ‘print “Put before first line\n” if $. == 1’ inFile.txt

    (from the perl FAQ):

      1. My finally correct version (may I request a preview feature?):

        diff -u <(head myfile) <(echo -e "my data goes here and ends at the period.\n`head myfile`") > mypatch; patch mypatch
  7. echo “MAINCARD_MSISDN,SUB_SOC,EXPIRY_DATE,S,U,” | cat – $spoolFile > /tmp/out && mv /tmp/out $spoolFile

    that line above works for. problem is if a have to run the script more than once. it will insert the same line again.. Any way to stop it?

    thanks

  8. Its worth mentioning that

    echo -e “DATA-Line-1\n$(cat input)” > input

    Is very ineficient and works only for small files, the larger files (e.g. 800Mb) crash the terminal and leave the file empty.


  9. echo -e "DATA-Line-1\n$(cat input)" > input

    dose not always work

    bash-4.1$ cat fish
    VALUE=${VALUE//[$'\t\r\n']}
    
    bash-4.1$ echo -e "DATA-Line-1\n$(cat fish)" > fish
    bash-4.1$ cat fish
    DATA-Line-1
    VALUE=${VALUE//[$'	
    ']}
    
  10. Thanks, this pointed me to just what I needed! I wanted to point out that your “Bash Only” way doesn’t need to be bash only – instead of using $(cat input), use `cat input` (use the backtick character). It does the same thing as $() in bash, but it works in most shells :D

Leave a Comment