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

Bash 使用sed以多行模式移动字符串,bash,awk,sed,Bash,Awk,Sed,如何使用sed来更改此设置: typedef struct { uint8_t foo; uint8_t bar; } a_somestruct_b; 到 我有许多“somestruct”结构需要转换。awk让您开始使用的解决方案: $ cat tst.awk /typedef struct/{p=1;next} # start capturing p && $1=="}" { split($2

如何使用sed来更改此设置:

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


我有许多“somestruct”结构需要转换。

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
}
给出:

$ 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
$awk'/typedef struct/{p=1;next}p&&$1=“}”{split($2,a,”);printf“%s_%s_%s=struct.\n”,“pre”,a[2],“post”;for(j=1;j)

检查输出是否符合您的要求后,为
sed
添加了
-i
选项以就地编辑文件。

您能告诉我们更改它们的标准是什么吗?因为根本不清楚如何在不知道条件的情况下编写代码。OP在指定他想要的内容方面不是很广泛。但我怀疑t
uint8
将是他在输入中遇到的唯一类型。当然,你可以在正则表达式中轻松更改,另一方面,你正在回答他的确切问题。是的,搜索的模式可以随时修改。我只是尝试提供一个
sed
方法来解决这个问题。
$ 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
$ 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')