从shell脚本中的<ex> </ex>开头和结尾标记的文件中删除字符串

时间:2017-03-04 10:31:39

标签: bash sed

我正在编写一个bash脚本来取消注释标记的开头 离;

/*<O33>*/
    //  here my code
/*</O33>*/

这是我的剧本,我成功取消了它。

sed -i "/^[ \t]*\/\*<O33>\*\//,/^[ \t]*\/\*<\/O33>\*\//s/\/\///g" $Path/DebugVersion.c

这就是结果:

/*<O33>*/
      here my code
/*</O33>*/

现在我正在尝试反向过程,在开始和结束标记之间推荐字符串,但我不知道该怎么做。

2 个答案:

答案 0 :(得分:0)

重新插入注释的任务有点棘手,因为您不希望在开始和结束行插入//标记。我最终得到了一个文件script.sed,其中包含:

\@/\*<O33>\*/@, \@/\*</O33>\*/@ {
    \@/\*</\{0,1\}O33>\*/@ ! s%\([[:space:]]*\)%&//%
}
然后我跑了:

$ sed -f script.sed data
 /*<O33>*/
        //here my code
    /*</O33>*/
$

由于要匹配的材料中存在/*,您的模式匹配会变得复杂。解决此问题的一种方法是更改​​sed的搜索字符,在这种情况下,使用\@告诉它@标记模式的结束。 (您可以选择方便的任何其他角色:=%也能正常运作。)第一行的格式为 patt1, patt2 {{ 1}}第一个模式查找{(注意大写字母O,而不是零),第二个模式查找/*<O33*//*</O33>*/开始对命令进行分组。这意味着从第一个模式到第二个模式的范围内的行将受到匹配括号{ ... {中包含的命令的约束。

第二行在模式匹配上使用略有不同的变体来识别开始和结束行(}是查找0或1个/\{0,1\}实例的经典sed方式;如果使用现代扩展正则表达式,则相当于/)。 /?运算符颠倒了匹配的意义;只有与结束标记不匹配的行才会进行!替换。例如,这可以避免在s%%%前插入//

/*<O33>*/操作会查找零个或多个前导空格字符(空格或制表符),并在其后面添加s%\([[:space:]]*\)%&//%。同样,这可以避免使用//,因为s///是替换文本的一部分。

这可以被压成一行,而不是需要一个单独的脚本文件,但我喜欢脚本文件,因为我不必打击shell。这不是一个大问题;没有引号 - 单,双或后 - 来混淆事物。除非需要将shell变量插入到脚本中,否则请在脚本周围使用单引号。如果你必须使用双引号,你必须加倍反斜杠,它会迅速变得繁琐。如果可以,请避免在脚本周围加双引号。

/

在GNU $ sed '\@/\*<O33>\*/@, \@/\*</O33>\*/@ { \@/\*</\{0,1\}O33>\*/@ ! s%\([[:space:]]*\)%&//%; }' data /*<O33>*/ //here my code /*</O33>*/ $ 中,尾随分号是可选的;在BSD(macOS)和经典sed中是必要的。

我顺便提一下,在退役sed脚本中,你有:

sed

s/\/\///g 可能不是一个好主意。如果你有:

g

然后取消注释操作将离开:

/*<O33>*/
//    printf("%s\n", __func__);  // Identify the function!
/*</O33*/

删除第二个评论标记。代码不会编译。放下/*<O33>*/ printf("%s\n", __func__); Identify the function! /*</O33*/ ;您只想删除行上的第一个注释标记。 (显然,如果您只使用g条评论来禁用代码块,这并不重要 - 但从长远来看它更安全。)

另请注意,如果您使用C预处理器在C或C ++中工作,那么您最好使用:

//

因为您不必编辑文件来启用或禁用代码;你可以简单地使用或不使用#ifdef O33 printf("%s\n", __func__); // Identify the function! #endif 或同等版本重新编译。

答案 1 :(得分:0)

我从Jonathan的回答和SLePort的答案中学习,我得到了它。

my_proj