Bash 使用sed以多行模式移动字符串
如何使用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
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在指定他想要的内容方面不是很广泛。但我怀疑tuint8
将是他在输入中遇到的唯一类型。当然,你可以在正则表达式中轻松更改,另一方面,你正在回答他的确切问题。是的,搜索的模式可以随时修改。我只是尝试提供一个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')