Cコードでマクロ定義を最適化しようとしています。同様に、Cファイル内のすべてのマクロを抽出し、この特定のマクロ定義の発生回数を見つける必要があります。
私のマクロ定義の形式は次のとおりです。
#MACRO_NAME定義DEFN_LINE1 \ DEFN_LINE2\ DEFN_LINE3
だから私の論理は
- 正規表現を使用して上記の出力をMacroLineExtract.txtファイルにリダイレクトして、「#define」で始まり、「\」で終わる行のリストを見つけます。
- MacroLineExtract.txtからすべての「#define」を削除==> MACRO_NAME DEFN_LINE1 \
- MACRO_NAMEの後のスペース===>末尾の文字列を削除してください。
- 上記の出力を、マイコードのMACROSリストのみを含むMacros.txtファイルに保存します。
- Macros.txt から 1 行ずつインポートし、コードで MACRO_NAME が何回表示されるかを調べる bash スクリプトを作成します。
私のCファイルで「#define」で始まり、「\」で終わるすべてのマクロを見つける正規表現/ awkを書くのに役立ちますか?より良い論理があれば提案してください。
答え1
使用活気に満ちたctags:
$ ectags --c-kinds=d *.[ch]
ectags
Vi / VimやEmacsなどのエディタがソースコードを簡単にナビゲートするために使用できる「タグファイル」を生成するために使用される「タグファイル」の拡張ctags
バージョン。etags
Cの構文規則を理解しているので、Cコードを解析できます(したがって正規表現について心配する必要はありません)。
私たちはCコードラインにのみ興味があると--c-kinds=d
聞きました。ectags
#define
これで、現在のディレクトリにtags
次の内容を含むファイル名ができました。
DEVELOPER bayes.h 225;" d
DIFFERENT bayes.h 227;" d
DIR_MIN bayes.h 338;" d
DNA bayes.h 242;" d
DOLLAR bayes.h 309;" d
DOLLO bayes.h 276;" d
DOWN bayes.h 215;" d
つまり、各行(複数のヘッダー行を除く)は、マクロ名、マクロを含むソースファイル、および行番号を識別します。マクロが複数のファイルで定義されている場合は、発生ごとに1回ずつ一覧表示されます。最後はd
タグタイプインジケータ(#define
s)です。
各マクロが定義された回数のみを計算したい場合:
$ cut -f 1 tags | uniq -c
答え2
awk
解析可能そしてARG_MAXを超えずに必要なファイル名をすべて渡すことができると仮定して、単一のジョブとして計算されます。
awk '$1=="#define"&&/\\$/ {n[$2]++} END {for(i in n) print n[i],i}' *.[ch]
# this includes #define's that are indented with whitespace,
# which the C language allows. If you really want only #defines
# that start exactly in column 1, use /^#define /&&/\\$/
# if you want the columns to line up change the print to something like
# printf "%6d %s\n",x[i],i
答え3
ファイルに次の行がある場合:
#MACRO_NAME定義DEFN_LINE1 \
その後、MACRO_NAMEの固有値を取得します。
cat yourCfile | grep '#define' | awk '{print $2}' | sort -u > macro_names
grep この "#define" を含む行を取得します。
awkはスペース/スペースをデフォルトのフィールド区切り文字として使用し、1行の各文字列を新しいフィールドとして扱います。したがって、ここではawkを使用して、「#define MACRO_NAME DEFN_LINE1 \」の2番目のフィールド「MACRO_NAME」を印刷します。
sort -u> Macro_namesはすべての重複エントリを削除し、すべてをファイルに出力します。
そして、マクロ名のリストを繰り返しながら、そのマクロ名を含む行数を見つけます。
for macro in $(cat macro_names); do
count=$(cat yourCfile | grep $macro | wc -l);
echo $macro appears $count times
done
「-l」フラグと一緒に「wc」コマンドは、標準入力から受け取った行数を印刷します。
答え4
sed '/#define/,\
/^\(.*[^\]\)*$/N
/\n\\/P;D'