ファイル内の「_DB」で終わるすべての関数宣言を見つけて、避けてperl
パイプしたいと思います。
たとえば、
prep_DB();
init_DB(DB *database, char *params[])
{
open_DB(database);
}
prep_DB() {
open_DB(database); // open
}
FILE * load_DB(const char * exppath, const char * expfname)
{}
2行目と2行目から最後の行までのみ一致する必要があります。この行はprep_DB() {
あってもなくてもよい。
現在、次のコマンドはすべての関数呼び出しを検索します。
grep -E '.*_DB(.*)' file
しかし、最後のセミコロンを否定するのに問題があります。これがどのように機能するかを説明するのに最も近いスレッドは次のとおりです。これ;しかし、セミコロンはそこにある提案が機能しないので特殊文字のようです。この制限をどのようにバイパスできますか?
答え1
これがfile.c
。
使用ctags
:
$ ctags file.c
これにより、次のファイルが作成されますtags
。
$ cat tags
init_DB file.c /^init_DB(DB *database, char *params[])$/
load_DB file.c /^FILE * load_DB(const char * exppath, const char * /
prep_DB file.c /^prep_DB() {$/
vi
これは関数定義と共に使用することも、vim
自動的に関数定義に移動することもできます。
cut
以下を使用してこのファイルを解析することもできますgrep
。
$ cut -f 1 tags | grep '_DB$'
init_DB
load_DB
prep_DB
Ubuntuシステムでは、インストール時ctags
に実際にexuberant-ctags
詳細なtags
出力が提供されます。
$ cat tags
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /[email protected]/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
init_DB file.c /^init_DB(DB *database, char *params[])$/;" f
load_DB file.c /^FILE * load_DB(const char * exppath, const char * expfname)$/;" f
prep_DB file.c /^prep_DB() {$/;" f
ここでは、関数定義のみを取得できることを確認できます。
$ awk '$NF == "f" && $1 ~ /_DB$/ { print $1 }' tags
init_DB
load_DB
prep_DB
awk
ここで重要なのは、Cコードを解析するスクリプトや正規表現で可能なすべてのプログラミングスタイルを考慮するよりも、専用のC言語パーサーを使用する方が良いことです。grep
あなたもできます。
$ ctags -x file.c
init_DB function 3 file.c init_DB(DB *database, char *params[])
load_DB function 12 file.c FILE * load_DB(const char * exppath, const char * expfname)
prep_DB function 8 file.c prep_DB() {
次に、必要な方法で解析/フィルタリングします。この数値は定義の行番号です。それはすべて「見つけたい」ということが何を意味するかによって異なります。
答え2
私は上記の20以上のコメントにディスカッションの概要を投稿することにしました。
次のコマンドの使用を提案した@don_crisstiがソリューションを提供しました。
$ grep -E '.*_DB([^;]*)$' <filename>
出力を生成する
init_DB(DB *database, char *params[])
prep_DB() {
FILE * load_DB(const char * exppath, const char * expfname)
彼の提案に従って、必要に応じて中間結果を除外するために次のコマンドを考えました。
$ grep -E '_DB\(.*\)$' <filename>