構造フィールドを抽出するためのテキスト処理

構造フィールドを抽出するためのテキスト処理

たとえば、構造体からフィールドを抽出しようとしています。

  typedef struct newstruct {
  long id;            
  uint32_t vtid;      
  struct HN* next;
} HashNode;

sed/awkを使用して構造体名を抽出し、その後に区切り文字でフィールドを抽出したい。

newstruct HashNode: long id, uint_32 vtid, struct HN* next

答え1

を使用するとかなり簡単になりますがawk、 を使用するとおそらく実行可能ですsed

を使用するとawk、各行で設定/リセットされる状態がありtypedef、各行は右中括弧で終わります。適切なawkスクリプトは次のようになります。

BEGIN {
    state = 0;
    typedef="";
    fields="";
}
/typedef[ ]+struct/{
    state = 1;
    typedef=$3;
    next;
}
/}.*;/ {
    if (state != 0) {
        sub("^.*}[  ]*","",$0);
        sub(";","",$0);
        sub(",$","",fields);
        printf "%s %s: %s\n", typedef, $0, fields;
        state = 0;
        fields = "";
        typedef = "";
    }
    next;
}
(state == 1){ 
    gsub("[     ]+"," ", $0);
    gsub(";",",",$0);
    fields = fields $0;
    next;
}

ここで、角かっこ[]タブはスペースとタブを囲みます (移植性を高めるため)。スクリプトには 4 つの部分があります。

  1. アクションBEGINは変数を初期化します(厳密には必要ではありませんが、一部の awk は初期化されていない変数に対して若干異なる処理を行います)
  2. 行に一致するパターンはtypedef、 の後に空白と単語 が続きますstruct。行には少なくとも 3 つのフィールドが必要であり、3 番目は typedef の名前として使用されます。
  3. 閉じ中括弧に一致するパターン。ファイルに他の内容が含まれている場合に備えて、アクションは がstate設定されているかどうかを確認します。 は$0現在の行です。最初の置換では、関心のある単語の前のすべてが削除され、2 番目の置換では、それに続くセミコロンが削除されます。3 番目の置換では、4 番目のアクション (以下) から取得した変数の後のカンマがfields空の文字列に変更されます。
  4. 他のすべての行に一致するパターンいつ stateが設定されています。前のアクションと同様に、これは置換を使用して、最初に複数の空白を 1 つの空白に減らし、次に末尾のセミコロンをカンマに変更することで、不要な部分を削除します。

そのファイルfoo.awkと入力データを呼び出してfoo.in、次のように awk を使用します。

awk -f foo.awk <foo.in

次のような行を一致させたい場合:

struct foo {

それよりも

typedef struct foo {

パターンは次のように記述できる

/^([  ]*typedef)?[  ]+struct[  ]+/{

(ここでも、角括弧内にはスペースとタブがそのまま入っています)。括弧はグループ疑問符は?それを0回以上繰り返すことを意味します。({線上の部分は実際にはアクションただし、指定されたスクリプトの行と一致するようにそのまま残しました。

参考文献:

答え2

sed -rn '
/typedef struct ([[:alnum:]_]+)\s+\{/!b
s//\1/; h
:X
n 
/}\s+([[:alnum:]_]+)/{
    s//\1/
    H
    g
    s/;//g
    s/(.*)\n(.*)\n(.*)\n(.*)\n(.*)/\1 \5: \2, \3, \4/
    p;b
}
s/\s*(.+);\s*/\1/
H
bX
' file

newstruct HashNode: long id, uint32_t vtid, struct HN* next

関連情報