É bastante simples com awk
, talvez possível com sed
.
Com awk
, você teria um estado definido / redefinido em cada linha de typedef
e seria concluído em cada linha com uma chave direita. Um script awk
adequado seria parecido com
BEGIN {
state = 0;
typedef="";
fields="";
}
/typedef[ ]+struct/{
state = 1;
typedef=$3;
next;
}
/}.*;/ {
if (state != 0) {
sub("^.*}[ ]*","",$0);
sub(";","",$0);
sub(",$","",fields);
printf "%s %s: %s\n", typedef, $0, fields;
state = 0;
fields = "";
typedef = "";
}
next;
}
(state == 1){
gsub("[ ]+"," ", $0);
gsub(";",",",$0);
fields = fields $0;
next;
}
em que os colchetes [
e ]
incluem um espaço e uma tabulação (para torná-lo portátil). Existem quatro partes no script:
- a ação
BEGIN
inicializa variáveis (não estritamente necessárias, mas alguns awks fazem coisas ligeiramente diferentes com variáveis não inicializadas) - o padrão que corresponde à linha com
typedef
, seguido de blank (s) e a palavrastruct
. Isso espera pelo menos 3 campos na linha, usando o terceiro como o nome do typedef. - um padrão para combinar com a chave de fechamento. Apenas no caso de seu arquivo ter outras coisas, a ação verificará se
state
foi definido. O$0
é a linha atual. A primeira substituição apaga tudo antes da palavra em que estamos interessados, e a segunda tira o ponto-e-vírgula depois dela. A terceira substituição muda uma vírgula após a variávelfields
que veio da quarta ação (abaixo), para uma string vazia. - um padrão que corresponde a todas as outras linhas quando
state
está definido. Como a ação anterior, isso usa a substituição para aparar as partes não desejadas, primeiro reduzindo vários espaços em branco para um único espaço em branco e, em seguida, alterando o ponto-e-vírgula à direita para uma vírgula.
Chame esse arquivo foo.awk
e seus dados de entrada foo.in
para usar o awk assim:
awk -f foo.awk <foo.in
Se você quisesse combinar linhas como esta:
struct foo {
em vez de
typedef struct foo {
então o padrão poderia ser escrito
/^([ ]*typedef)?[ ]+struct[ ]+/{
(novamente, com um espaço literal e uma tabulação entre colchetes). Os parênteses marcam um grupo e o ponto de interrogação ?
diz para repetir isso zero ou mais vezes. (O {
na linha denota o início da ação , mas deixei-a lá para corresponder à linha no script fornecido).
Leitura adicional: