Reputation: 98
Since I searched for this so many times and could not find a simple (failsafe) solution.
Consider the following snippet. Of which I want to move the block BLOCK_ONE
to the end of the Range RANGE_END
.
if(condition)
string(RANGE_BEGIN # RANGE_BEGIN
"$<$<BLOCK_ONE>:" # BLOCK_ONE BEGIN
"Boost::system;"
"Boost::filesystem;"
">" # BLOCK_ONE END
"$<$<BLOCK_TWO>:"
"otherlib;"
"somelib;"
">"
"$<$<BLOCK_THREE>:"
"comctl32;"
">"
) # RANGE_END
elseif(othercondition)
string(RANGE_BEGIN # RANGE_BEGIN
"$<$<BLOCK_ONE>:" # BLOCK_ONE BEGIN
"pthread;"
"Zlib::minizip;"
">" # BLOCK_ONE END
"$<$<BLOCK_FOUR>:"
"somelib;"
">"
) # RANGE_END
endif()
if(condition)
string(RANGE_BEGIN # RANGE_BEGIN
"$<$<BLOCK_TWO>:"
"otherlib;"
"somelib;"
">"
"$<$<BLOCK_THREE>:"
"comctl32;"
">"
"$<$<BLOCK_ONE>:" # BLOCK_ONE BEGIN
"Boost::system;"
"Boost::filesystem;"
">" # BLOCK_ONE END
) # RANGE_END
elseif(othercondition)
string(RANGE_BEGIN # RANGE_BEGIN
"$<$<BLOCK_FOUR>:"
"somelib;"
">"
"$<$<BLOCK_ONE>:" # BLOCK_ONE BEGIN
"pthread;"
"Zlib::minizip;"
">" # BLOCK_ONE END
) # RANGE_END
endif()
Upvotes: 1
Views: 73
Reputation: 58483
This might work for you (GNU sed):
sed -n '/BLOCK_ONE/{h;:a;n;H;/">"/!ba;:b;n;/)/!{p;bb};H;x};p' file
Focus on a line containing BLOCK_ONE
, then gather up further lines in the hold space until a line containing ">"
. Print further lines until a line containing )
, then append this line to the hold space, swap to the hold space and print the those lines. All other lines are printed as normal.
Upvotes: 1
Reputation: 98
Warning: This won't work correctly if BLOCK_ONE is not found. (It will move the parenthesis to the next parenthesis in a range.)
Here comes the solution I used:
sed '/RANGE_BEGIN/,/)/{ # Do the following within given range (/BEGIN/,/END/)
/BLOCK_ONE/,/">"/{ # Do the following within given range (/BEGIN/,/END/)
/BLOCK_ONE/h # BLOCK_ONE containing line: overwrite hold space with it
/BLOCK_ONE/!H # BLOCK_ONE non-containing line: append it to hold space
d # Delete what you read (past tense)
}
/)/{ # End of RANGE
x # eXchange pattern with hold space
# (replace the line with everything you collected before,
# keeping the replaced line in hold space)
G # Add newline and Get the line we saved with x printed
}
}' InputFile.cmake
For people preferring one line, here it is:
sed '/RANGE_BEGIN/,/)/{/BLOCK_ONE/,/">"/{/BLOCK_ONE/h;/BLOCK_ONE/!H;d};/)/{x;G}}' InFile
Upvotes: 1