5

I have been trying to insert a file as the first line of another with following SED command, without much success. Each time the file is inserted after line 1. Is there a switch that will inserted before line 1?

sed -i '1r file1.txt' file2.txt

Thanks in advance.

4 Answers 4

7

With the N command

Provided that file2.txt has more than one line (else see the other section):

sed -i -e '1 { r file1.txt' -e 'N; }' file2.txt

The trick is to defer the printing of the first line with the N command.

From the manual:

N

Append the next line of input into the pattern space.

With the e command

Provided that file2.txt is not empty (else just do a copy):

sed -i -e '1 e cat file1.txt' file2.txt

GNU sed provides a e command that executes the command in parameter. The result is output is immediately.

From the manual:

e [COMMAND]

This command allows one to pipe input from a shell command into pattern space. Without parameters, the `e' command executes the command that is found in pattern space and replaces the pattern space with the output; a trailing newline is suppressed.

If a parameter is specified, instead, the `e' command interprets it as a command and sends its output to the output stream.

Note that, unlike the 'r' command, the output of the command will be printed immediately; the 'r' command instead delays the output to the end of the current cycle.

2
  • Hi, What do the curly braces do in the first example ?
    – Stelios
    Commented Sep 29, 2022 at 13:11
  • @Stelios They associate a group of commands to a single address (here line 1)
    – xhienne
    Commented Oct 12, 2023 at 0:31
6

The sed command r will place the contents of the specified file in the output before reading the next line of input. Unfortunately you can't specify 0 as the address for this command, so there's no way to insert the contents of a file before the first line of input (without poking around with the hold space).

You could, however, just use plain old cat. It is, after all, the command for concatenating files:

$ cat file1.txt file2.txt >out && mv out file2.txt

To be sure you're writing to a temporary file that does not already exist, one may use the mktemp utility:

$ tmp="$(mktemp)" && cat file1.txt file2.txt >"$tmp" && mv "$tmp" file2.txt

This is slightly awkward on the command line, but a good precaution in any script that needs to write to a temporary file.

6
  • 1
    I suggest with the use of mktemp: tmp=$(mktemp) && cat file1.txt file2.txt > $tmp && mv $tmp file2.txt ?
    – Danduk82
    Commented Jan 14, 2017 at 21:18
  • @Danduk82 That's a reasonable suggestion.
    – Kusalananda
    Commented Jan 14, 2017 at 21:22
  • Thought of that - the text files are over 1.5 GB, takes a while. but if that is the only option! it will have to do! thank you.
    – user68650
    Commented Jan 14, 2017 at 21:23
  • 1
    all good - did not take a long as i expected. ! 8-)
    – user68650
    Commented Jan 14, 2017 at 21:38
  • 1
    @user68650: At a bare minimum, the functionality that you want requires reading file1.txt and file2.txt in their entirety, and writing a new version of file2.txt (containing the original content of the two files, concatenated).  mktemp and mv are very low-cost operations (except when mv really does a copy); why would you expect there to be an answer that’s more efficient than this? Commented Jan 15, 2017 at 22:43
5

If you're determined to avoid cating to an explicit temporary file (or via a buffer such as sponge), then it looks like ed at least will accept a 0-address for its r command:

ed -s file2.txt << EOF
0r file1.txt
wq
EOF

or equivalently

printf '0r file1.txt\nwq\n' | ed -s file2.txt
1
  • 1
    Yes, ed is always a good choice when we don't need the s (streaming) of sed. Commented Nov 6, 2017 at 13:09
2

If you want to insert the same file on top of multiple files within the same directory, the following based on Kusalananda's answer might be used:

for i in file*; do tmp="$(mktemp)" && cat file1 $i >"$tmp" && mv "$tmp" $i; done
1
  • 1
    That should work. Nice lateral thinking, and welcome to unix.se Commented Nov 6, 2017 at 12:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .