
たとえば、構造からフィールドを抽出したいとします。
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つの部分で構成されています。
- これ
BEGIN
は変数を初期化します(必ずしも必要ではありませんが、一部のawksは初期化されていない変数に対して少し異なる操作を実行します)。 typedef
行の後にスペースと単語が続くパターンを一致させますstruct
。この行には、3番目のフィールドをtypedefの名前として使用して少なくとも3つのフィールドが必要です。- 閉じる中かっこに一致するパターン。ファイルに他の項目がある場合に備えて、操作はその項目がすでに設定
state
されていることを確認します。これが$0
現在の行です。最初の置換は関心のある単語の前のすべての項目を削除し、2番目の置換はその後のセミコロンを削除します。 3番目の置換は、fields
4番目の操作(下)の変数の後のコンマを空の文字列に変更します。 - 他のすべての行に一致するパターンいつ
state
設定しました。前の操作と同様に、置換を使用して不要な部分を切り取り、最初に複数のスペースを1つのスペースに減らしてから、末尾のセミコロンをコンマに変更します。
foo.awk
次のように、awkを使用して入力データとしてこのファイルを呼び出しますfoo.in
。
awk -f foo.awk <foo.in
次の行を一致させるには:
struct foo {
代わりに
typedef struct foo {
その後、パターンは次のように書くことができます。
/^([ ]*typedef)?[ ]+struct[ ]+/{
(やはり文字通り空白とタブがある角括弧)。かっこ内に表示されているものグループ疑問符は?
0回以上の繰り返しを示します。 (これ{
オンラインは実際に始まりを意味します行動しかし、与えられたスクリプトの行と一致するようにそのままにしました。)
追加資料:
- awk - パターンスキャンと処理言語(POSIX)
- 9.4 拡張正規表現(POSIX)
答え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