Skip to main content
added 45 characters in body
Source Link
Stéphane Chazelas
  • 586.9k
  • 96
  • 1.1k
  • 1.7k

For in-place editing with GNU sed, there's the -i option. The Read line command, (which reads one line from a named file, then each line after that when run again), is useful here. Two line version:

sed -i `1'1,5{R file2
        d}`' file1

Notes:

  • Read line's output is not changed by the delete that follows. R inserts each line from file2 after d deletes a line from file1. The d cannot go first, (if it doesdid, the R outputs nothing);command would not be run, Rd needs an existing line to work with.is like next in awk)

  • The Read line (like all commands taking a file name) requires the filename be delimited by a linefeed or an unquote. The usual ; command separator is ignored, R interprets R file2; as a filename ending with a literal ";". The same with spaces, R interprets R file2 ; as a filename ending with a literal " ;"

  • R is not affected by -i, so file2 won't be changed.

Therefore toTo fit that on one line requires breaking up the curly braces with an unquote and, one can pass two -e switchesxpressions which sed joins with linefeeds to form the sed script:

sed -i -e '1,5{R file2' -e 'd}' file1

Otherwise, you don't need sed:

{ head -n 5 file2; tail -n +6 file1; } > file3

In the general case, to replace $x1 to $y1 lines of file1 with $x2 to $y2 lines of file2:

sed "$x2,\$!d;$y2 q" file2 | sed -i -e "$x1 r /dev/stdin" -e "$x1,$y1 d" file1

Or:

{
  head -n "$((x1 - 1))"
  tail -n "+$x2" < file2 | head -n "$((y2 - x2 + 1))"
  tail -n "+$((y1 - x1 + 2))"
} < file1 > file3 

For in-place editing with GNU sed, there's the -i option. The Read line command, (which reads one line from a named file, then each line after that when run again), is useful here. Two line version:

sed -i `1,5{R file2
d}` file1

Notes:

  • Read line's output is not changed by the delete that follows. R inserts each line from file2 after d deletes a line from file1. The d cannot go first, (if it does R outputs nothing); R needs an existing line to work with.

  • Read line requires the filename be delimited by a linefeed or an unquote. The usual ; command separator is ignored, R interprets R file2; as a filename ending with a literal ";". The same with spaces, R interprets R file2 ; as a filename ending with a literal " ;"

  • R is not affected by -i, so file2 won't be changed.

Therefore to fit that on one line requires breaking up the curly braces with an unquote and -e switches:

sed -i -e '1,5{R file2' -e 'd}' file1

Otherwise, you don't need sed:

{ head -n 5 file2; tail -n +6 file1; } > file3

In the general case, to replace $x1 to $y1 lines of file1 with $x2 to $y2 lines of file2:

sed "$x2,\$!d;$y2 q" file2 | sed -i -e "$x1 r /dev/stdin" -e "$x1,$y1 d" file1

Or:

{
  head -n "$((x1 - 1))"
  tail -n "+$x2" < file2 | head -n "$((y2 - x2 + 1))"
  tail -n "+$((y1 - x1 + 2))"
} < file1 > file3 

For in-place editing with GNU sed, there's the -i option. The Read line command, (which reads one line from a named file, then each line after that when run again), is useful here. Two line version:

sed -i '1,5{R file2
        d}' file1

Notes:

  • Read line's output is not changed by the delete that follows. R inserts each line from file2 after d deletes a line from file1. The d cannot go first, (if it did, the R command would not be run, d is like next in awk)

  • The Read line (like all commands taking a file name) requires the filename be delimited by a linefeed. The usual ; command separator is ignored, R interprets R file2; as a filename ending with a literal ";". The same with spaces, R interprets R file2 ; as a filename ending with a literal " ;"

  • R is not affected by -i, so file2 won't be changed.

To fit that on one line, one can pass two -expressions which sed joins with linefeeds to form the sed script:

sed -i -e '1,5{R file2' -e 'd}' file1

Otherwise, you don't need sed:

{ head -n 5 file2; tail -n +6 file1; } > file3

In the general case, to replace $x1 to $y1 lines of file1 with $x2 to $y2 lines of file2:

sed "$x2,\$!d;$y2 q" file2 | sed -i -e "$x1 r /dev/stdin" -e "$x1,$y1 d" file1

Or:

{
  head -n "$((x1 - 1))"
  tail -n "+$x2" < file2 | head -n "$((y2 - x2 + 1))"
  tail -n "+$((y1 - x1 + 2))"
} < file1 > file3 
Tweak, as per @don_crissti.
Source Link
agc
  • 7.4k
  • 4
  • 25
  • 54

For in-place editing with GNU sed, there's the -i option. The Read line command, (which reads one line from a named file, then each line after that when run again), is useful here. Two line version:

sed -i `1,5{R file2
d}` file1

Notes:

  • Read line's output is immune tonot changed by the delete that follows. R inserts each line from file2 after d deletes a line from file1. The d cannot go first, (if it does R outputs nothing); R needs an existing line to work with.

  • Read line requires the filename be delimited by a linefeed or an unquote. The usual ; command separator is ignored, R interprets R file2; as a filename ending with a literal ";". The same with spaces, R interprets R file2 ; as a filename ending with a literal " ;"

  • R is not affected by -i, so file2 won't be changed.

Therefore to fit that on one line requires breaking up the curly braces with an unquote and -e switches:

sed -i -e '1,5{R file2' -e 'd}' file1

Otherwise, you don't need sed:

{ head -n 5 file2; tail -n +6 file1; } > file3

In the general case, to replace $x1 to $y1 lines of file1 with $x2 to $y2 lines of file2:

sed "$x2,\$!d;$y2 q" file2 | sed -i -e "$x1 r /dev/stdin" -e "$x1,$y1 d" file1

Or:

{
  head -n "$((x1 - 1))"
  tail -n "+$x2" < file2 | head -n "$((y2 - x2 + 1))"
  tail -n "+$((y1 - x1 + 2))"
} < file1 > file3 

For in-place editing with GNU sed, there's the -i option. The Read line command, (which reads one line from a named file, then each line after that when run again), is useful here. Two line version:

sed -i `1,5{R file2
d}` file1

Notes:

  • Read line's output is immune to the delete that follows. R inserts each line from file2 after d deletes a line from file1. The d cannot go first, (if it does R outputs nothing); R needs an existing line to work with.

  • Read line requires the filename be delimited by a linefeed or an unquote. The usual ; command separator is ignored, R interprets R file2; as a filename ending with a literal ";". The same with spaces, R interprets R file2 ; as a filename ending with a literal " ;"

  • R is not affected by -i, so file2 won't be changed.

Therefore to fit that on one line requires breaking up the curly braces with an unquote and -e switches:

sed -i -e '1,5{R file2' -e 'd}' file1

Otherwise, you don't need sed:

{ head -n 5 file2; tail -n +6 file1; } > file3

In the general case, to replace $x1 to $y1 lines of file1 with $x2 to $y2 lines of file2:

sed "$x2,\$!d;$y2 q" file2 | sed -i -e "$x1 r /dev/stdin" -e "$x1,$y1 d" file1

Or:

{
  head -n "$((x1 - 1))"
  tail -n "+$x2" < file2 | head -n "$((y2 - x2 + 1))"
  tail -n "+$((y1 - x1 + 2))"
} < file1 > file3 

For in-place editing with GNU sed, there's the -i option. The Read line command, (which reads one line from a named file, then each line after that when run again), is useful here. Two line version:

sed -i `1,5{R file2
d}` file1

Notes:

  • Read line's output is not changed by the delete that follows. R inserts each line from file2 after d deletes a line from file1. The d cannot go first, (if it does R outputs nothing); R needs an existing line to work with.

  • Read line requires the filename be delimited by a linefeed or an unquote. The usual ; command separator is ignored, R interprets R file2; as a filename ending with a literal ";". The same with spaces, R interprets R file2 ; as a filename ending with a literal " ;"

  • R is not affected by -i, so file2 won't be changed.

Therefore to fit that on one line requires breaking up the curly braces with an unquote and -e switches:

sed -i -e '1,5{R file2' -e 'd}' file1

Otherwise, you don't need sed:

{ head -n 5 file2; tail -n +6 file1; } > file3

In the general case, to replace $x1 to $y1 lines of file1 with $x2 to $y2 lines of file2:

sed "$x2,\$!d;$y2 q" file2 | sed -i -e "$x1 r /dev/stdin" -e "$x1,$y1 d" file1

Or:

{
  head -n "$((x1 - 1))"
  tail -n "+$x2" < file2 | head -n "$((y2 - x2 + 1))"
  tail -n "+$((y1 - x1 + 2))"
} < file1 > file3 
Typo.
Source Link
agc
  • 7.4k
  • 4
  • 25
  • 54

For in-place editing with GNU sed, there's the -i option. The Read line command, (which reads one line from a named file, then each line after that when run again), is useful here. Two line version:

sed -i `1,5{R file2
d}` file1

Notes:

  • Read line's output is immune to the delete that follows. R inserts each line from file2 after d deletes a line from file1. The d cannot go first, (if it does R outputs nothing); R needs an existing line to work with.

  • Read line requires the filename be delimited by a linefeed or an unquote. The usual ; command separator is ignored, R interprets R file2; as a filename ending with a literal ";;". The same with spaces, R interprets R file2 ; as a filename ending with a literal "* ;*"" ;"

  • R is not affected by -i, so file2 won't be changed.

Therefore to fit that on one line requires breaking up the curly braces with andan unquote and -e switches:

sed -i -e '1,5{R file2' -e 'd}' file1

Otherwise, you don't need sed:

{ head -n 5 file2; tail -n +6 file1; } > file3

In the general case, to replace $x1 to $y1 lines of file1 with $x2 to $y2 lines of file2:

sed "$x2,\$!d;$y2 q" file2 | sed -i -e "$x1 r /dev/stdin" -e "$x1,$y1 d" file1

Or:

{
  head -n "$((x1 - 1))"
  tail -n "+$x2" < file2 | head -n "$((y2 - x2 + 1))"
  tail -n "+$((y1 - x1 + 2))"
} < file1 > file3 

For in-place editing with GNU sed, there's the Read line command, (which reads one line from a named file, then each line after that when run again). Two line version:

sed -i `1,5{R file2
d}` file1

Notes:

  • Read line's output is immune to the delete that follows. R inserts each line from file2 after d deletes a line from file1. The d cannot go first, (if it does R outputs nothing); R needs an existing line to work with.

  • Read line requires the filename be delimited by a linefeed or an unquote. The usual ; command separator is ignored, R interprets R file2; as a filename ending with a literal ";". The same with spaces, R interprets R file2 ; as a filename ending with a literal "* ;*"

  • R is not affected by -i, so file2 won't be changed.

Therefore to fit that on one line requires breaking up the curly braces with and unquote and -e switches:

sed -i -e '1,5{R file2' -e 'd}' file1

Otherwise, you don't need sed:

{ head -n 5 file2; tail -n +6 file1; } > file3

In the general case, to replace $x1 to $y1 lines of file1 with $x2 to $y2 lines of file2:

sed "$x2,\$!d;$y2 q" file2 | sed -i -e "$x1 r /dev/stdin" -e "$x1,$y1 d" file1

Or:

{
  head -n "$((x1 - 1))"
  tail -n "+$x2" < file2 | head -n "$((y2 - x2 + 1))"
  tail -n "+$((y1 - x1 + 2))"
} < file1 > file3 

For in-place editing with GNU sed, there's the -i option. The Read line command, (which reads one line from a named file, then each line after that when run again), is useful here. Two line version:

sed -i `1,5{R file2
d}` file1

Notes:

  • Read line's output is immune to the delete that follows. R inserts each line from file2 after d deletes a line from file1. The d cannot go first, (if it does R outputs nothing); R needs an existing line to work with.

  • Read line requires the filename be delimited by a linefeed or an unquote. The usual ; command separator is ignored, R interprets R file2; as a filename ending with a literal ";". The same with spaces, R interprets R file2 ; as a filename ending with a literal " ;"

  • R is not affected by -i, so file2 won't be changed.

Therefore to fit that on one line requires breaking up the curly braces with an unquote and -e switches:

sed -i -e '1,5{R file2' -e 'd}' file1

Otherwise, you don't need sed:

{ head -n 5 file2; tail -n +6 file1; } > file3

In the general case, to replace $x1 to $y1 lines of file1 with $x2 to $y2 lines of file2:

sed "$x2,\$!d;$y2 q" file2 | sed -i -e "$x1 r /dev/stdin" -e "$x1,$y1 d" file1

Or:

{
  head -n "$((x1 - 1))"
  tail -n "+$x2" < file2 | head -n "$((y2 - x2 + 1))"
  tail -n "+$((y1 - x1 + 2))"
} < file1 > file3 
Added explanatory text about the `R` commands gotchas.
Source Link
agc
  • 7.4k
  • 4
  • 25
  • 54
Loading
added 354 characters in body
Source Link
Stéphane Chazelas
  • 586.9k
  • 96
  • 1.1k
  • 1.7k
Loading
Source Link
Stéphane Chazelas
  • 586.9k
  • 96
  • 1.1k
  • 1.7k
Loading