最後にセミコロンが一致しないように正規表現をgrepします。

最後にセミコロンが一致しないように正規表現をgrepします。

ファイル内の「_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>

関連情報