使用awk将命名空间添加到C#文件

时间:2009-09-29 18:45:43

标签: regex awk

我有几个C#类,其中没有将命名空间添加到文件中。示例文件如下所示(Test.cs):

using System;
using System.IO;

public partial class MyTestClass
{
    protected void MyTestVoid()
    {
        // Magic happens here
    }
}

如您所见,没有名称空间声明。我希望输出为:

using System;
using System.IO;

namespace MyNamespace
{
    public partial class MyTestClass
    {
       protected void MyTestVoid()
       {
            // Magic happens here
       }
    }
}

我要做的是编写一个快速脚本,基本上在类定义周围插入命名空间。我决定尝试awk,所以我创建了一个像这样的awk文件:

$0 ~ "namespace MyNamespace"
{
    foundTrigger = 1;
}

!foundTrigger
{
    if ($0 ~ "/^[:space:]*public[:space:]{1}(partial[:space:])*class/")
    {
        print "namespace MyNamespace\n{\n" $0;
    }
    else
    {
        print $0;
    }
}

END
{
    if (!foundTrigger)
        print "}";
}

对文件执行此操作(如上所述)之后,它实际上没有做任何事情(除了在文件底部添加“}”之外)。

这就是我理解我的正则表达式的用法:

^[:space:]*public[:space:]{1}(partial[:space:])*class

该行必须以零或多个空格开头,后跟单词“public”,后跟一个空格,后跟零或更多(“partial”后跟空格),后跟单词“class”。因此这些行应匹配:

public class Test
public partial class Test

这些不匹配:

public void Test()
public string Test

但是如果我对egrep使用类似的正则表达式:

egrep "^[[:space:]]*public[[:space:]]{1}(partial[[:space:]])*class" *.cs

我得到了这个结果:

public partial class MyTestClass

阅读awk的手册页显示:

  

正则表达式是egrep中的扩展类型。

所以我不确定为什么我的awk脚本无效。任何帮助表示赞赏。也许有更好的方法来完成我想要做的事情?

2 个答案:

答案 0 :(得分:0)

也许以稍微不同的方式看待问题会有所帮助。不要试图匹配正则表达式之后/之前的行,而是尝试抓取整个using“段落”本身。附加到该文件,然后完成文件。

    BEGIN { 
        RS = ""; # Read by "paragraphs".  
                 # Records are separated by blank lines. 
    }
    {
        if ( NR == 1 )
        {
            print $0,"\n\nnamespace MyNameSpace;\n{";
            RS = "\n";
        }
        else
        {
            print "\t", $0;  # For indenting
        }
    }
    END {
        print "}";
    }

编辑:最初我插入了“using”指令。他想要“命名空间”(和适当的语法):几乎完全相同的问题。固定的。

答案 1 :(得分:0)

这应该这样做:

/^ *public (partial )*class / {trigger = 1 ; print "namespace MyNamespace"}
{print $0}
END {if(trigger) print "} //end of space"}

但你对空白似乎非常严格。我放松了一点,但后来我不相信自己的打字。