SED: copy lines from a file to specific line in another file

55,252

Solution 1

Doing this with sed requires some additional shell trickery. Assuming bash, you could use

sed -i 18r<(sed '16,80!d' file1) file2

Where <(sed '16,80!d' file1) is substituted with the name of a pipe from which the output of sed '16,80!d' file1 can be read.

Generally, I feel that it is nicer to do this with awk (if a little longer), because awk is better equipped to handle multiple input files. For example:

awk 'NR == FNR { if(FNR >= 16 && FNR <= 80) { patch = patch $0 ORS }; next } FNR == 18 { $0 = patch $0 } 1' file1 file2

This works as follows:

NR == FNR {                       # While processing the first file
  if(FNR >= 16 && FNR <= 80) {    # remember the patch lines
    patch = patch $0 ORS
  }
  next                            # and do nothing else
}
FNR == 18 {                       # after that, while processing the first file:
  $0 = patch $0                   # prepend the patch to line 18
}
1                                 # and print regardless of whether the current
                                  # line was patched.

However, this approach does not lend itself to in-place editing of files. This is not usually a problem; I'd simply use

cp file2 file2~
awk ... file1 file2~ > file2

with the added advantage of having a backup in case things go pear-shaped, but in the end it's up to you.

Solution 2

I have done something similar using:

    head -80 file | tail -16 > patch

Check the documentation for your local versions of head and tail, and change the two integers to suit your requirements.

Share:
55,252
mYself
Author by

mYself

Updated on November 22, 2020

Comments

  • mYself
    mYself over 3 years

    I can do this using the following example. The 1st command will output the lines 16...80 from file1 to patch, while the 2nd will insert the contents of patch after line 18 to file2:

    sed -n 16,80p file1>patch
    sed -i 18rpatch file2
    

    However, I would like to copy directly from one file to another without using a temporary file in-between, in one command using sed (not awk, etc.). I'm pretty sure this is possible, just don't know how.