0

I have a text file that looks something like this:

Some text here. This text is not replaced.

---

And then a wild block appears!
It has stuff in it that I'm trying to replace.

---

The block is no more. Nothing to replace here. 

And another text file with contents to insert:

A multi-
line thing to replace. 
This block is not demarcated 
in the same way
as the other

And what I'm trying to do is replace the ----demarcated block with the contents of the text file, so that it looks like this:

Some text here. This text is not replaced.

A multi-
line thing to replace. 
This block is not demarcated 
in the same way
as the other

The block is no more. Nothing to replace here. 

This is similar to this question, but I don't think that applies, since what I'm dealing with is a multi-line block, and it doesn't seem like sed is very good at that. Can awk or ruby or something do this?

Community
  • 1
  • 1
Jonathan
  • 9,074
  • 8
  • 45
  • 80
  • 1
    Quite related: [How to insert a line in a file between two blocks of known lines (if not already inserted previously), using bash?](http://stackoverflow.com/q/8971314/1983854) – fedorqui 'SO stop harming' Jun 29 '15 at 13:56
  • That question is about inserting text, but replacing a multi-line block is a little harder. Since those sed operations operate on single lines, some other method is required. – Jonathan Jun 29 '15 at 14:06
  • Yes, true. Probably a merge of that one with [sed insert file content after specific pattern match](http://stackoverflow.com/a/16715488/1983854) would make it. I am just commenting it as a helper, not as a close vote. – fedorqui 'SO stop harming' Jun 29 '15 at 14:08
  • Unfortunately the second question only deals with inserting text, not replacing text. – Jonathan Jun 29 '15 at 14:17

1 Answers1

4

Untested but will be close if not exactly what you want:

awk '
NR==FNR { file1 = file1 $0 RS; next }
/---/ {
    if (f) {
        printf "%s", file1
    }
    f = !f
    next
}
!f
' file1 file2
Ed Morton
  • 157,421
  • 15
  • 62
  • 152
  • This only seems to print the contents of `file2`. – Jonathan Jun 29 '15 at 14:40
  • You're probably puting the input files in the wrong order on the command line. Try swapping them. – Ed Morton Jun 29 '15 at 14:49
  • Cool. You're right--that does it. Swapping `file1` and `file2` in the last line of this script does the trick. – Jonathan Jun 29 '15 at 14:57
  • 1
    `NR==FNR` compares the number of lines read across all files (NR) with the number of lines read in the current file (FNR) and if they are equal (which can only be true while reading the first non-empty file) then evaluate to true. `file1 = file1 $0 RS; next` build up a string named `file` from the contents of the first file read. The block starting with `/---/` prints that string instead of the text between 2 `---` lines in file2. The `!f` invokes the default action of printing the current record for every line of file2 that's not between `---` pairs. – Ed Morton Jun 29 '15 at 15:37
  • 1
    Get the book Effective Awk Programming, 4th Edition, by Arnold Robbins and add some `print` statements to the code to investigate/understand what it does further. – Ed Morton Jun 29 '15 at 15:37
  • 1
    Also, the FNR==NR "trick" is well explained in http://backreference.org/2010/02/10/idiomatic-awk/ – fedorqui 'SO stop harming' Jun 29 '15 at 16:05