2017-04-04 11 views
1

式が特定のパターンと一致するC++コードベースから、 'if'ブロックをテキストファイルにコピーしようとしています。これはgrep/awk/sedなどの組み合わせを使って可能ですか?.cppファイルからパターンに一致する 'if'ブロックを抽出する

私のようなコードを含むファイルがある場合:私は含む//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 
    } 
} 

//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 
    } 
} 

が好きな私は、結果を取得したいと思いそれ以外の一致/不一致のブロックifは、繰り返し入力する場合でも、タブインデントを保持する必要はありません。

grepを使って私が望む表現にマッチさせるのに問題はありませんが、それは私に「if」ブロックの開始点を含む行しか与えません(これは良いスタートです)。

ご協力いただければ幸いです。

+0

不一致が一致する 'if'の内部にある場合はどうなりますか?それは '// Code'ですか? –

+0

あなたはあなたのC++コードからマッチを削除したいということを意味するのでしょうか? – Markus

+0

@JamesBrownその場合、私はそれを "コード"と考えています。実際には、中かっこの間に何かを見つけたいと思っています。 – AMackie

答えて

1

$ 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 
} 

それは{}それぞれが自分のライン上にあることを期待しています。まあ、その行に他のものがあるかもしれませんが、{または}の1つだけです。オハイオ州と@ 123の括弧がない場合はも適用されます。これは大括弧で囲まれた箇所を解析する必要があります。おそらくまだ実行可能、私は偵察。

+0

これを説明していただけますか? –

+0

これはうまくいきません.cを減らすことはありません(1の場合のみ、埋め込み式のifでは使用できません)。もしあれば、それはファイルの残りの部分を書き出します。 – 123

+0

@ 123あなたは正しいかもしれません。 –

-2

this answerをご覧ください。例えば

(Perlの正規表現を使用しない):すべてのコードを仮定し

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

私はこれが答えだとは思わない! –

+0

いいえ、私は – Markus

+0

私はそれが挑戦だと思っています:) –

2

は、あなたの質問と同じフォーマットされ、何の浮遊ブラケット(文字列か何かで言う)が存在しないされ、これは

を動作するはずです

文字列を検索したい文字列に置き換えます。 awkでは

+0

これはそれでした! perlに精通していないので、これを適切に解析する必要がありますが、私はそれが何をしているのかを見ていると思います。私はクローズドブレースを見つけるまで、{と}をそれぞれ追跡しなければならないと思った。各一致 'if'式の最初に一度ファイル名を出力する簡単な方法はありますか? – AMackie

+0

@AMackieええ、基本的には、ブラケットに遭遇した場合にカウンタに加算または減算するだけです。カウンタが0より大きい場合は印刷します。 'print 'を' print'に変更しますか?$ ARGV:$ _ "' – 123

+0

うん、それは働いた! – AMackie

0
forループで

とのsed以下が働くだろう:

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

これは、追加した各ファイルを取得してしまう「:」ファイル名にして、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 

我々は左ブレースブラケットの数をカウントし、それを変数leftに置き、右中括弧の数を数えて右に置き、最後に変数diffの中の2つの間の差を置く このdiff変数は、必要な追加変数を持つ変数(varb)を作成するために使用されますブレースブラケット。この変数は、最終的にoutputfileに追加され、必要な構文を完成させます。

関連する問題