1

What is the most efficient way to replace file's content between specific line numbers with another file?

Here is a sample:

main.txt:

a b c
d e f
g h i
j k l

new.part.txt

x y z
p q r
s t u

The block of text starting at line 2 and ending at line 3 of main.txt is replaced with new.part.txt. The desired file is as follow:

a b c
x y z
p q r
s t u
j k l

This answer is for the case when range of the desired block is defined via marker strings. I need a solution that uses line numbers for defining range of the desired block.

Kadir
  • 145
  • 1
  • 6

2 Answers2

2
start=2
end=3

{
  head -n $((start-1)) old.txt
  cat new.txt
  tail -n $((end+1)) old.txt
} > merged.txt
u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • I prefer this style, for readability. But looks like the `tail -n $((end+1)) old.txt` is not correct. You have to read in the number of lines of the file, and subtract your end position. `tail -n $(($(wc -l < old.txt)-end)) old.txt` – Marshall Jan 02 '17 at 23:53
2

You don't use bash at all.

The Bourne Again shell is a shell. The actual utility programs for doing this are not part of the shell, and are largely shell-agnostic. grawity's answer uses shell features, but mainly for parameterization.

Here's how to do it with ex, editing the file in place:

ex main.txt << EOT
2,3d
1r new.part.txt
w
EOT

Here's how one does it with sed, writing the changed data to standard output:

sed -e '1r new.part.txt' -e '2,3d' main.txt
JdeBP
  • 26,613
  • 1
  • 72
  • 103