使用SED以多线模式移动字符串



我该如何使用sed来更改此问题:

typedef struct
{
    uint8_t foo;
    uint8_t bar;
} a_somestruct_b;

to

pre_somestruct_post = restruct.
 int8lu('foo').
 int8lu('bar')

我有许多转换的"弹性"结构。

awk 解决方案以使您开始:

$ cat tst.awk
/typedef struct/{p=1;next}                                # start capturing
p && $1=="}" {
   split($2,a,"_")                                        # capture "somestruct"
                                                          # in a[2]
   printf "%s_%s_%s = restruct.n", "pre", a[2], "post"   # possibly "pre" and "post" 
                                                          # should be "a" and "b"
                                                          # here? 
   for (j=1;j<=i;j++) printf "%s%sn", s[j], (j<i?".":"") # print saved struct fields
   delete s; i=0; p=0                                     # reinitialize
}
p && NF==2{
   split($1, b, "_")                                      # capture type
   sub(/;/,"",$2)                                         # remove ";"
   s[++i]=sprintf("  %slu('%s')", b[1], $2)               # save struct field in 
                                                          # array s
}

使用文件输入.txt:

对此进行测试
$ cat input.txt
typedef struct
{
  uint8_t foo;
  uint8_t bar;
} a_atruct_b;
typedef struct {
  uint8_t foo;
  uint8_t bar;
} a_bstruct_b;
typedef struct
{
  uint8_t foo;
  uint8_t bar;
} a_cstruct_b;

给出:

$ awk -f tst.awk input.txt
pre_atruct_post = restruct.
  uint8lu('foo').
  uint8lu('bar')
pre_bstruct_post = restruct.
  uint8lu('foo').
  uint8lu('bar')
pre_cstruct_post = restruct.
  uint8lu('foo').
  uint8lu('bar')

同样的事情,就像一个单线:

$ awk '/typedef struct/{p=1;next} p && $1=="}" {split($2,a,"_");printf "%s_%s_%s = restruct.n", "pre", a[2], "post";for (j=1;j<=i;j++) printf "%s%sn", s[j], (j<i?".":"");delete s; i=0; p=0} p && NF==2 {split($1, b, "_");sub(/;/,"",$2);s[++i]=sprintf("  %slu('%s')", b[1], $2)}' input.txt
$ cat sed_script
/typedef struct/{                           # find the line with "typedef struct"
  n;n;                                      # Go to next two line
  /uint8_t/{                                # Find the line with "uint8_t"
    s/uint8_t (.*);/int8lu(x271x27)./;   # substitute the line, i.e. int8lu('foo').
    h;n;                                    # copy the pattern space to the hold space,
                                            # then go to next line
    s/uint8_t (.*);/int8lu(x271x27)/;    # substitute the line, i.e. int8lu('bar')
    H;n                                     # append the pattern space to the hold space
                                            # then go to next line
  };
  s/.*_(.*)_.*/pre_1_post = restruct./p;   # substitute and print the line,
                                            # i.e., pre_somestruct_post = restruct.
  g;p                                       # copy the hold space to the pattern space 
                                            # and then print
}
$ sed -rn -f sed_script input
pre_somestruct_post = restruct.
    int8lu('foo').
    int8lu('bar')

检查输出是您所需的,添加了-i选项以供 sed编辑到适当的文件。

最新更新