awk:ヘッダファイルの列挙ブロック内でコードブロックを一致させる

awk:ヘッダファイルの列挙ブロック内でコードブロックを一致させる

列挙内の#ifdefを削除するためにC ++ヘッダーを解析しようとしています。私が使用している headerParser モジュールに #ifdef を含む列挙型をスキップするバグがあるため、これが必要です。

ファイルを収集して準備するシェルスクリプトがあります。その後、Pythonスクリプトが呼び出され、最終出力が生成されます。 Pythonファイルは一般的なので、シェルスクリプト内で "#ifdef"ブロックを削除するだけです。

テキスト部分は次のとおりです。

  typedef enum fixedsample
{
element 1,
element 2,
element 3,
#ifdef XYZ
element 4,
element 5,
#endif
} FIXEDNAME;

ifdefはその要素を必要としないので、削除する必要があります。また、列挙名 "fixedsample" と "FIXEDNAME" はすべてのファイルに対して正確で変更されません。

この目的でawkを使用できますか?どんな助けでも大変感謝します。

編集:「typedef enum ConstantName」と「}CONSTANT;」がすべてのファイルに表示されます。したがって、#ifdefはそのブロック内でのみ検索できます。他の#ifdefは削除されません。

答え1

awkこれは範囲とフラグを使用して行うことができます。たとえば、次のようになります。

awk '/enum fixedsample/,/} FIXEDNAME/ { e=1 } e && /^#ifdef/,/^#endif/ { next } { e=0; print }' foo.hpp

このsedバージョンにはフラグも必要なく、入れ子になった範囲のみが必要なため、範囲#ifdef ... #endif内のすべての範囲が削除されenum ... }ますd

sed '/enum fixedsample/,/} FIXEDNAME/{; /^#ifdef/,/^#endif/d; }' foo.hpp

実際のバージョンでは、誤検出の可能性を減らすために、より正確なモードを使用する必要があります。

答え2

すべての言語の構文で正規表現を使用することはほとんど良い考えではありません。これは非常に脆弱で、マイナーな理由(ラインコメントなど)が#ifdef混乱する可能性があります。バグのある別のパーサーでバグのあるパーサーを修正するのは…いくら言ってもおかしいです。

質問を理解したら、読んでください。

場合によっては、ブロック#ifdef全体を削除するのに役立ちます(ただし、本当に定義されていないように処理しますか?)。

sed '/ enum /,/}/!b
  /#ifdef/!b
  :loop
  N
  /#endif/!bloop
  d' file.h

説明する:

  • / enum /,/}/!benum維持 -}範囲外のすべての行
  • /#ifdef/!bまた、内部のすべてに触れないでください。#ifdef
  • :loopはい、一度発生したら#ifdef繰り返す必要があります。
  • Nこれで行の追加を開始します。
  • /#endif/!bloop私たちが見つけるまで#endif
  • その後、d当社が収集したすべてのコンテンツ#ifdef#endif当社が収集したコンテンツの両方を削除します。

関連情報