使用sed以多行模式移动字符串

时间:2017-09-24 23:24:24

标签: bash awk sed

我如何使用sed来改变它:

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

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

我有很多" somestruct"结构转换。

2 个答案:

答案 0 :(得分:1)

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%s\n", 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
}

使用文件input.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%s\n", 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

答案 1 :(得分:0)

$ 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(\x27\1\x27)./;   # 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(\x27\1\x27)/;    # 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选项以编辑文件。