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