Q:

Parse input into blocks enclosed in curly braces with Sed

Two files:
File 1
{
foo
}
{
bar
}

File 2
foo
}
{
bar
}

(Only difference is file 1 starts with open curly brace)
The following expression works on file 2, but not file 1, why? (And how to fix?):
sed '1!N; s/}\n{/},\n{/' < file1 or file2

I don't know why the open curly brace, 2 lines before a match, would cause this behavior. I'd like to know the reason why sed is getting tripped up and how to fix it. But I'm also open to other ways to insert a , between }\n{ besides sed.

A:

Is this what you want (uses GNU awk for multi-char RS):
$ awk -v RS='}\n{' '{ORS=(RT?"},\n{":"")} 1' file1
{
foo
},
{
bar
}

$ awk -v RS='}\n{' '{ORS=(RT?"},\n{":"")} 1' file2
foo
},
{
bar
}

A:

It isn't the opening brace, it is the extra line. Put anything on that line (even nothing) and your script stops working.
Your script is strictly pair-based. It only works when the closing } falls on an even line.
Your Sed script says 1!N - for every line that isn't the first line, read the next line into the pattern space, then attempt the s/// transformation.
Then the end of the script happens, and Sed prints the pattern space, discards it, and reads the next line. You only ever pair up two lines at once, starting from the second line.
A file of
}
{

wouldn't get modified correctly either, but
f
}
{

will.
This Sed command
sed '/}$/{N;s/}\n{/},\n{/}'

will work for files that don't contain }\n}\n{ (it'll miss those).
For something more robust you either need something like awk or someone better at sed than I am to come up with a smarter script.

