如何将文本块移动到范围的末尾(使用sed)?

如何将文本块移动到范围的末尾(使用sed)?,sed,text-processing,Sed,Text Processing,因为我搜索了这么多次,没有找到一个简单的(故障保护)解决方案 问题 考虑以下代码段。其中我要将块块_ONE移动到范围的末尾范围_end if(condition) string(RANGE_BEGIN # RANGE_BEGIN "$<$<BLOCK_ONE>:" # BLOCK_ONE BEGIN "Boost::system;" "Boost::filesystem;"

因为我搜索了这么多次,没有找到一个简单的(故障保护)解决方案

问题 考虑以下代码段。其中我要将块
块_ONE
移动到范围的末尾
范围_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(条件)
字符串(范围开始#范围开始
“$”#块_一端
"$" 
"$"
)#范围#结束
elseif(其他条件)
字符串(范围开始#范围开始
“$”#块_一端
"$"
)#范围#结束
endif()
目标
if(条件)
字符串(范围开始#范围开始
"$" 
"$"
“$”#块_一端
)#范围#结束
elseif(其他条件)
字符串(范围开始#范围开始
"$"
“$”#块_一端
)#范围#结束
endif()

警告:如果未找到BLOCK_ONE,则此功能将无法正常工作。(它会将括号移动到范围内的下一个括号。)

下面是我使用的解决方案:


sed'/RANGE_BEGIN/,/)/{在给定范围内(/BEGIN/,/END/)执行以下操作
/BLOCK_ONE/,/“>”/{#在给定范围内(/BEGIN/,/END/)执行以下操作
/BLOCK_ONE/h#BLOCK_ONE包含行:用它覆盖保留空间
/BLOCK_ONE/!H#BLOCK_ONE非包含行:将其追加到保留空间
删除你读到的内容(过去时)
}
/)/{#范围结束
x#带保持空间的交换模式
#(将该行替换为您以前收集的所有内容,
#将更换的管路保持在保持空间内)
G#添加换行符并打印我们保存的x行
}
}'InputFile.cmake
对于喜欢一条线的人,这里是:

sed '/RANGE_BEGIN/,/)/{/BLOCK_ONE/,/">"/{/BLOCK_ONE/h;/BLOCK_ONE/!H;d};/)/{x;G}}' InFile
这可能适用于您(GNU-sed):


将焦点放在包含
块的行上,然后在保留空间中收集更多行,直到包含
“>”
的行。打印更多行,直到有一行包含
,然后将此行附加到保留空间,交换到保留空间并打印这些行。所有其他行都按正常方式打印。

如果您有答案,可以将其作为答案发布。否则,如果你寻求改进,考虑把问题张贴出来,你会建议把答案分解成一个答案?WiktorStribiżewIt是一种常见的做法,是的。哦,我会尽快检查这个。在你的帮助下,我可能最终不理解sed中的分支。这个工具太棒了。
sed '/RANGE_BEGIN/,/)/{/BLOCK_ONE/,/">"/{/BLOCK_ONE/h;/BLOCK_ONE/!H;d};/)/{x;G}}' InFile
sed -n '/BLOCK_ONE/{h;:a;n;H;/">"/!ba;:b;n;/)/!{p;bb};H;x};p' file