从.cpp文件中提取与模式匹配的"if"块

Extracting 'if' blocks matching a pattern from .cpp files

本文关键字:if 模式匹配 cpp 文件 提取      更新时间:2023-10-16

我正在尝试将表达式与特定模式匹配的C++代码库中的任何"if"块复制到文本文件中。这可以使用 grep/awk/sed 等的某种组合吗?

如果我的文件包含以下代码:

//File1.cpp
if(/*matching-expression-1*/)
{
    //Code
}
//File2.cpp
if(/*non-matching-expression*/)
{
    if(/*matching-expression-2*/)
    {
        //Code
    }
}
//File3.cpp
if((/*matching-expression-3*/)
{
    if(/*non-matching-expression*/)
    {
        //Code
    }
}

我想得到这样的结果:

//OutputFile.txt
File1.cpp:
if(/*matching-expression-1*/)
{
    //Code
}
File2.cpp:
if(/*matching-expression-2*/)
{
    //Code
}
File3.cpp:
if((/*matching-expression-3*/)
{
    if(/*non-matching-expression*/)
    {
        //Code
    }
}

我对包含其他匹配/不匹配if块的//Code块感到满意,即使这会导致重复条目,并且没有必要保留制表符缩进。

我使用 grep 来匹配我想要的表达式没有问题,但这只给了我包含"if"块开头的行(这是一个好的开始!(,但我不确定如何继续。

任何帮助将不胜感激!

假设您的所有代码的格式都与您的问题相同,并且没有杂散的括号(例如字符串或其他东西(,那么这应该可以工作

perl -ne 'if(/if(STRING)/){$_.=<>;$b+=/{/g;}if($b > 0){print;$b+=/{/g;$b-=/}/g}' file

将字符串替换为要搜索的任何内容。

在 awk 中:

$ awk '/*matching-expression/{f=1}f{c+=sub(/{/,"{");if(sub(/}/,"}") && --c==0)f=0;print $0}' file
if(/*matching-expression-1*/)
{
    //Code
}
    if(/*matching-expression-2*/)
    {
        //Code
    }
if((/*matching-expression-3*/)
{
    if(/*non-matching-expression*/)
    {
        //Code
    }
}

解释:

/*matching-expression/ { f=1 }   # flag up at match
f {                               # when flag is up
    c+=sub(/{/,"{")               # { increments counter
    if(sub(/}/,"}") && --c==0)    # if count is about be 0
        f=0                       # flag down
    print $0                      # print when flag is up
}

它希望每个{}都在自己的路线上。好吧,这条线上可以有其他东西,但只有一个{}.哦,是的,@123 的无杂散括号也适用于这里,我认为这需要解析括号周围的引号。可能仍然可行,我侦察。

使用 for 循环和 sed 可以执行以下操作:

for var in $(ls *.cpp);do echo -e $var":";sed -n '/*matching-expression/,/}/p' $var;echo -e "n";done > outputfile

这将获取每个文件,然后在文件名中添加一个":",然后使用 sed,显示从匹配表达式到 FIRST } 的代码部分,将结果输出到输出文件中。

唯一的问题是它可能会错过关闭大括号

为了克服这个问题,您可以添加:

left=$(cat outputfile | grep "{" | wc -l)
right=$(cat outputfile | grep "}" | wc -l)
diff=$(echo $(($left-$right)))
varb="";for ((i=0;i<$diff;i++));do varb=$varb"}";done
echo $varb >> outputfile

这里我们计算左大括号的数量并将其放在变量 left 中,计算右大括号括号的数量并将其放在右边,最后将两者之间的差异放在变量 diff 中然后,此差异变量用于形成具有必要附加大括号的变量 (varb(。此变量最终添加到输出文件中以完成必要的语法。

看看这个答案,它可能会帮助你。

例如(不使用Perl regex(:

grep -zo "if\s*(condition)\s*{[^}]*}" File1.cpp