62

How can we append text in a file via a one-line command without using io redirection?

apoorv020
  • 5,420
  • 11
  • 40
  • 63
  • 3
    this sounds like an XY problem (http://www.perlmonks.org/index.pl?node_id=542341), why do you need append without redirection? – Joel Berger Jan 09 '11 at 16:32
  • There are plenty of tools for file manipulaton including Perl, sed (see below), awk, tee -a, etc. – Joel Berger Jan 09 '11 at 16:37
  • 1
    @Joel : could be true. I asked the question for a colleague, and really don't know what the exact problem is. – apoorv020 Jan 09 '11 at 16:43
  • 6
    Typically useful when manipulating files with sudo (the IO are under the user's environment), and you sometimes have a limited set of tools allowed via sudo. – Thomas BDX Jul 19 '13 at 13:39

5 Answers5

67

If you don't mind using sed then,

$ cat test 
this is line 1
$ sed -i '$ a\this is line 2 without redirection' test 
$ cat test 
this is line 1
this is line 2 without redirection

As the documentation may be a bit long to go through, some explanations :

  • -i means an inplace transformation, so all changes will occur in the file you specify
  • $ is used to specify the last line
  • a means append a line after
  • \ is simply used as a delimiter
Loufylouf
  • 697
  • 5
  • 13
taskinoor
  • 45,586
  • 12
  • 116
  • 142
  • I get `sed: -i may not be used with stdin` on macOS 13.3 bash shell. Probably cos of https://stackoverflow.com/a/21243111/259453 – volvox Apr 05 '18 at 20:52
5

If you just want to tack something on by hand, then the sed answer will work for you. If instead the text is in file(s) (say file1.txt and file2.txt):

Using Perl:

perl -e 'open(OUT, ">>", "outfile.txt"); print OUT while (<>);' file*.txt

N.B. while the >> may look like an indication of redirection, it is just the file open mode, in this case "append".

Joel Berger
  • 20,180
  • 5
  • 49
  • 104
5

You can use the --append feature of tee:

cat file01.txt | tee --append bothFiles.txt 
cat file02.txt | tee --append bothFiles.txt 

Or shorter,

cat file01.txt file02.txt | tee --append bothFiles.txt 

I assume the request for no redirection (>>) comes from the need to use this in xargs or similar. So if that doesn't count, you can mute the output with >/dev/null.

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
  • Piping will also step out of xargs.. So not much better than `>>`, the best approach here is using `sh -c` – Tofandel Apr 21 '21 at 21:05
  • @Tofandel, I meant before `xargs`. You can pipe as much as you want before `xargs`; but `>>` will require you to end the pipe, which then can't continue to `xargs`. – Ondra Žižka Aug 02 '22 at 21:46
4

You can use Vim in Ex mode:

ex -sc 'a|BRAVO' -cx file
  1. a append text

  2. x save and close

Zombo
  • 1
  • 62
  • 391
  • 407
  • I like the approach in this answer, but it doesn't seem to append to the file. A simple example like this: for fidx in $(seq 1 6); do ex -sc "a|Something${fidx}" -cx test.txt; done produces text that is not ordered:cat test.txt Something2 Something1 Something3 Something4 Something5 Something6. How do I make it go to the end of the file before appending? Interestingly, it only seems to happen for the first two lines of an empty file. If I run the example multiple times everything is ordered correctly. – Mark E. Hamilton Jan 19 '18 at 01:40
  • 1
    Try putting a $ before the a, which references the end of the file: ex -sc "$a|Something${fidx}" -cx test.txt – Andy Apr 06 '20 at 21:44
1

On Linux/GNU systems, the simplest and cleanest solution is:

dd of=oldfile oflag=append conv=notrunc

Simple and clean, because no quoting or backslashitis is required.

Unfortunately, this also doesn't work on BSD (and so, on Darwin), because their dd has no oflag . Argh! Can anyone suggest how to do it with the BSD dd ?

q.undertow
  • 246
  • 2
  • 8