11

I always do this to append text to a file

echo "text text text ..." >> file
# or
printf "%s\n" "text text text ..." >> file

I wonder if there are more ways to achieve the same, more elegant or unusual way.

  • 2
    As I already said, it's not only that. echo "a\nb" will print something different than printf "%s\n" "a\nb", in ~all the shells but bash. You cannot assume that the two are similar. – mosvy Feb 14 at 5:47
  • 1
    Note that you can group commands together (a ; b ; c) >> file – Thorbjørn Ravn Andersen Feb 15 at 13:44
22

I quite like this one, where I can set up a log file at the top of a script and write to it throughout without needing either a global variable or to remember to change all occurrences of a filename:

exec 3>> /tmp/somefile.log
...

echo "This is a log message" >&3
echo "This goes to stdout"
echo "This is written to stderr" >&2

The exec 3>dest construct opens the file dest for writing (use >> for appending, < for reading - just as usual) and attaches it to file descriptor #3. You then get descriptor #1 for stdout, #2 for stderr, and this new #3 for the file dest.

You can join stderr to stdout for the duration of a script with a construct such as exec 2>&1 - there are lots of powerful possibilities. The documentation (man bash) has this to say about it:

exec [-cl] [-a name] [command [arguments]] If command is specified, it replaces the shell. [...] If command is not specified, any redirections take effect in the current shell [...].

11

Here are few other ways to append text to a file.

  1. Using tee

    tee -a file <<< "text text text ..."
    
  2. Using awk

    awk 'BEGIN{ printf "text text text ..." >> "file" }'
    
  3. Using sed

    sed -i '$a text text text ...' file
    sed -i -e "\$atext text text ..." file
    

Sources:

  • 2
    sed -i does not so much append as overwrite with an extended version. Normally not much of an issue, but it can be if the file is sparse, linked, or actively being read. – David G. Feb 16 at 12:44
9

Using a here-document approach:

cat <<EOF >> file
> foo
> bar
> baz
> EOF

Tests:

$ cat file
aaaa
bbbb

$ cat <<EOF >> file
> foo
> bar
> baz
> EOF

$ cat file
aaaa
bbbb
foo
bar
baz
  • 5
    Why downvote? This is a valid answer tho. – annahri Feb 14 at 14:50
  • @annahri See updated answer with tests. – Paulo Tomé Feb 14 at 15:28
  • 1
    This is very, very useful in scripts. – Thorbjørn Ravn Andersen Feb 15 at 13:45
  • @ThorbjørnRavnAndersen Thank you :) – Paulo Tomé Feb 15 at 13:46
4

See dd(1) man page:

dd conv=notrunc oflags=append bs=4096 if=myNewData of=myOldFile
  • This is creative, but can you use a line of string instead of an input file? – annahri Feb 14 at 14:23
  • @annahri yes certainly, dd conv=notruct oflag=append of=destination <<<'Some string of text' – roaima Feb 14 at 15:42
  • 1
    @roaima that's shell dependent though. Not all shells support the <<< herestring construct. I have no idea what dd would do in those cases, would it be safe? – terdon Feb 15 at 16:04
  • 1
    @annahri. My bad: I scrolled down under "Each CONV symbol may be:" on the man page, and missed the bit where the list changes to "Each FLAG symbol may be:". – Paul_Pedant Feb 15 at 17:20
  • 1
    I tested dd with <<< in dash. It throws "Syntax error: redirection unexpected" with status 2, so dd itself is not even invoked. – Paul_Pedant Feb 15 at 17:37
3

Using the Unix file editors. Both GNU and BSD version.

Using ed(1) with printf

printf '%s\n' '$a' 'foo bar baz' . w | ed -s file.txt

The bash specific but more cryptic syntax using the $' ' shell quoting and a herestring

ed -s file.txt <<< $'$a\nfoo bar baz\n.\nw'

Using ex(1) with printf

printf '%s\n' '$a' 'foo bar baz' . x | ex -s file.txt

The bash specific but more cryptic syntax $' ' shell quoting and a herestring

ex -s file.txt <<< $'$a\nfoo bar baz\n.\nx'
  • 1
    ed, ex, and other text editors do not so much append as overwrite with an extended version. Normally not much of an issue, but it can be if the file is sparse, linked, or actively being read. – David G. Feb 16 at 12:51
  • @DavidG. Thank you for that wonderful comment. – Jetchisel Feb 16 at 13:42
1
cat >> file
first line
second line
...
last line

Hit Enter at the last line then Ctrl + D.

-1

Since no one has mentioned, this is another way to append text to a file.

Use any text editor like vi, nano, vim. Follow below steps for vi and vim.

Step 1:

vi filename

Step 2: Press Shift g, to go to the last line. Press i to go to insert mode from command mode.

Step 3: Add the text you want to append

Step 4: Press Esc to come to command mode. Press :wq to write and quit the text editor.

For Nano,

Step 1:

nano filename

. Go to last line pressing following keys Ctrl + _ and then Ctrl + V

Step 2: Add the text to the file. To save press Ctrl + o to write to file and Ctrl+x to exit

  • The sequence you gave does not work with either vim nor vi please test that before posting. – Jetchisel Feb 14 at 13:19
  • 2
    In vi and its clones, Gi will insert at the beginning of the last line. Perhaps you intended GA or Go? – roaima Feb 14 at 22:43
  • It is shift g. I corrected it. – Ruban Savvy Feb 16 at 10:47
  • You have one more issue. Please refer to roaima's comment. @RubanSavvy – annahri Feb 16 at 15:19

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