sed动态替换基于行号的文本

时间:2018-06-19 06:14:28

标签: shell

我正在寻找从//到/ * * /

的bash脚本注释

我得到了部分工作 sed -i '14s ///// * /'a.c 这有点像//带* /如何在最后添加* /。

Originl脚本

#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;  
}

1 个答案:

答案 0 :(得分:1)

最简单的解决方案

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

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

这里的关键是:

  1. 使用%代替/来标记s///(或s%%%)命令的各个部分。
  2. \(…\)
  3. 中捕获评论的文字
  4. 将其替换为\1(前面有/*,后跟*/和单个空格。
  5. 处理问题数据的直接副本,输出为:

    #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!
    

    这种东西不应该折磨任何实际的代码库,但是编译器编写者必须正确处理的垃圾类型。