首页 > 解决方案 > sed 根据行号动态替换文本

问题描述

我正在寻找从 // 到 /* */ 的 bash 脚本注释

我得到了部分工作 sed -i '14s/////*/' ac 这就像 // with */ how to add */ 最后。

原始脚本

#include <stdio.h>


char buffer[10] = {'0'};  // comment1 

int main() 
{
    printf("Hello World");  // Comment2 

    return 0;
}

预期文件

#include <stdio.h>


char buffer[10] = {'0'};     /* comment1 */

int main()
{
    printf("Hello World"); /*  Comment2  */

    return 0;  
}

标签: shell

解决方案


最简单的解决方案

假设问题中显示的所需输出中的特殊间距是无意的:

sed 's%// *\(.*\)%/* \1 */%'

这里的关键是:

  1. 使用%而不是标记(或)命令/的单独部分。s///s%%%
  2. 捕获评论的文本\(…\)
  3. 将其替换为\1( 前面/*和后面*/以及单个空格。

处理问题数据的直接副本,输出为:

#include <stdio.h>


char buffer[10] = {'0'};  /* comment1  */

int main() 
{
    printf("Hello World");  /* Comment2  */

    return 0;
}

改善空间处理

评论后有尾随空格——丑陋!我们可以小心地解决这个问题:

sed 's%//[[:space:]]*\(.*[^[:space:]]\)[[:space:]]*$%/* \1 */%'

在打开注释之后匹配零个或多个空格//,并且匹配到行尾的可选空格字符串之前的最后一个非空格。这会产生:

#include <stdio.h>


char buffer[10] = {'0'};  /* comment1 */

int main() 
{
    printf("Hello World");  /* Comment2 */

    return 0;
}

您可以先处理所有尾随空白,无论如何这可能是一个好主意,使用:

sed -e 's/[[:space:]]\{1,\}$//' -e 's%//[[:space:]]*\(.*\)%/* \1 */%'

产生:

#include <stdio.h>


char buffer[10] = {'0'};  /* comment1 */

int main()
{
    printf("Hello World");  /* Comment2 */

    return 0;
}

这与之前的输出不同,它后面没有空格main()

正确的评论处理是困难的!

请注意,这个简单的代码很容易被有效的 C 混淆,例如:

printf("// this is not a comment\n");

充分理解 C 以不犯该错误是不明智sed的。不太严重的是,它会遗漏一些正式评论的有效但不可信的字符序列,例如:

/\
/this is a comment\
and this is also part of the comment\
    even    with    extra    spaces

如果你允许三元组(不要),那么:

/??/
/??/
This is part of the comment started two lines before!

这种东西不应该影响任何实际的代码库,而是编译器编写者必须正确处理的那种垃圾。


推荐阅读