Detecting and concatenating a multi-line structure using sed
So, given that I have some type of data structure like this within a segment of code:
struct apple {
int type, color;
Apple app;
};
// ... more code
I want to take the full struct definition (and any other struct definitions in the file) and compress them into one line (so the file product would look something like:
struct apple { int type, color; Apple app; };
).
This is part of a homework assignment. I just learned sed in lecture not a week or so ago, and I'm very unsure as to how to do something like this. As such, if you feel uncomfortable answering things outright, I would appreciate if you could point me in the right direction so that I can learn how to use this utility correctly.
I'm assuming that one could accomplish things with sed by detecting the struct definition, and then keep reading each line into a global buffer until a } is found (I'm assuming there are no unions or anything in the struct definition). There seems to be a lot of power in this program though, and I can't find any great开发者_如何学运维 introductions to it.
I'd do something in the line of this:
$ sed -n '/struct/,/};/p' input | sed -e ':a;N;$!ba;s/\n//g'
struct apple { int type, color; Apple app;};
The construct /foo/,/bar/
selects all lines (inclusive) between patterns.
The N
command appends a newline and the next line to current pattern space. Then the famous s///
command gets executed which replaces the newline character with nothing, i.e. join of lines.
there may be better way to solve this problem, e.g. awk maybe with tr. However since you mentioned that this is homework, and must be done by sed, I wrote the below commands (one liner :D ). note, there are two "sed" command. hope it could be accepted.
command to solve the problem:
sed -rn '/^struct/{x;s/.*/#/g;x;p;n};
/\};/ {x;/#/{s/#//;x;p;n}};
x; /#/{x;p}' yourFile | sed -r ':a;N; s/\n//g;s/\};/&\n/g; ba;'
now let's do a test, I created a file named t.c. see the content:
kent$ cat t.c
struct apple1 {
int type, color;
Apple app;
};
// ... more code
// ... more code
// ... more code
// ... more code
function abc(para){
foo;
bar;
return ;
}
struct apple2 {
int type, color;
Apple app;
};
// ... more code
// ... more code
// ... more code
struct apple3 {
int type, color;
Apple app;
};
// ... more code
now play my sed commands with the t.c baby:
kent$ sed -rn '/^struct/{x;s/.*/#/g;x;p;n};
/\};/ {x;/#/{s/#//;x;p;n}};
x; /#/{x;p}' t.c | sed -r ':a;N; s/\n//g;s/\};/&\n/g; ba;'
struct apple1 { int type, color; Apple app;};
struct apple2 { int type, color; Apple app;};
struct apple3 { int type, color; Apple app;};
精彩评论