例如,我正在尝试从结构中提取字段。
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