Search code examples
awksedreplacepattern-matchingopenfoam

Using sed to replace a pattern between curly braces where line immediately before the opening curly brace has a known word


I would like to change:

inlet
{
    type    patch;
    ...
}
outlet
{
        type  patch;
} 

to

inlet
{
    type    wall;
    ...
}
outlet
{
        type  patch;
} 

As a first attempt to achieve this, I tried to limit the range between inlet and outlet and replace "patch" with wall.

echo "inlet { patch } outlet" | sed "/^\(inlet [^ ]*\) .* \([^ ]*\)$/s//\1 wall \2/"

which gave output :

inlet { wall outlet

The last curly bracket is missing.

echo "inlet {patch} outlet {patch}"| sed "/inlet/,/outlet/{s/patch/wall/}"

gave output :

inlet {wall} outlet {patch}

However, I need to make sure that the "patch" that is replaced by wall shall have a "type" in the same line. It is this part I need to resolve now.


Solution

  • This might work for you (GNU sed):

    sed -E '/^inlet$/{n;/^\{$/{:a;N;/^\}$/M!ba;s/^(\s+type\s+)\S+/\1wall;/M}}' file 
    

    Search for line containing inlet only.

    Print it and fetch the next line.

    If that line contains only {, fetch subsequent lines until one containing only }.

    Now substitute a line beginning and separated by white space, two words: the first being type and then replace the second word by wall;.

    N.B. The use of the M flag in both regexp and the substitution commands, that bound the regexp by line i.e. the anchors respect the ^ and $ anchors, in a multiline string.