我正在尝试复制到文本文件中,如果'来自C ++代码库的块,其中表达式与特定模式匹配。这可能是使用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
}
}
我可以使用包含其他匹配/不匹配//Code
块的if
块,即使这会导致重复输入,并且选项卡缩进也不是必需的被保留。
我可以毫不费力地使用grep来匹配我想要的表达式,但这只会给我包含' if'的开头的行。阻止(这是一个好的开始!)但我不确定如何继续。
任何帮助都将不胜感激!
答案 0 :(得分:2)
假设您的所有代码的格式与您的问题相同,并且没有流浪括号(例如字符串或其他内容),那么这应该有效
perl -ne 'if(/if\(STRING\)/){$_.=<>;$b+=/{/g;}if($b > 0){print;$b+=/{/g;$b-=/}/g}' file
将字符串替换为您要搜索的内容。
答案 1 :(得分:1)
在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&#39> 没有流浪支架也适用于此,我需要解析括号周围的引号。可能仍然可行,我重新考虑。
答案 2 :(得分:0)
使用for循环和sed可以使用以下内容:
for var in $(ls *.cpp);do echo -e $var":";sed -n '/\*matching-expression/,/}/p' $var;echo -e "\n";done > outputfile
这将获取每个文件,然后添加&#34;:&#34;到文件名然后用sed,显示匹配表达式到FIRST的代码部分,将结果输出到outputfile。
唯一的问题是它可能会错过关闭括号括号
为了克服这个问题,您可以添加:
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
这里我们计算左括号括号的数量并将其放在变量左边,计算右括号括号的数量并将其放在右边然后最后将两者之间的差异放在变量diff中 然后使用此diff变量形成带有必要的附加支撑架的变量(varb)。最后将此变量添加到outputfile以完成必要的语法。
答案 3 :(得分:-2)