
例如,我正在嘗試從結構中提取字段。
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;
}
其中[
和]
括號括起空格和製表符(以使其可移植)。該腳本有四個部分:
- 此
BEGIN
操作初始化變數(不是絕對必要的,但有些 awks 對未初始化的變數執行略有不同的操作) - 與 的行匹配的模式
typedef
,後面跟著空格和單字struct
。預計該行至少有 3 個字段,使用第三個字段作為 typedef 的名稱。 - 與右花括號匹配的模式。以防萬一您的文件中有其他內容,該操作會檢查是否
state
已設定。這$0
是目前行。第一個替換刪除了我們感興趣的單字之前的所有內容,第二個替換刪除了其後面的分號。第三次替換fields
將來自第四個操作(如下)的變數後面的逗號更改為空字串。 - 與所有其他行相符的模式什麼時候
state
已設定。與前面的操作一樣,這使用替換來修剪掉不需要的部分,首先將多個空格減少為單個空格,然後將結尾的分號更改為逗號。
呼叫該檔案foo.awk
和您的輸入資料foo.in
來使用 awk,如下所示:
awk -f foo.awk <foo.in
如果你想匹配這樣的行:
struct foo {
而不是
typedef struct foo {
那麼該模式可以寫成
/^([ ]*typedef)?[ ]+struct[ ]+/{
(同樣,方括號中帶有文字空格和製表符)。括號中標示的是團體問號?
表示重複零次或多次。 (這{
線上實際上表示開始行動,但我將其留在那裡以匹配給定腳本中的行)。
延伸閱讀:
- 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