analisa uma gramática de marcação realmente simples com um script de shell

0

Eu tenho que analisar um arquivo, um tipo de arquivo de configuração, que está adotando uma gramática bem simples: existem 2 tipos de blocos de múltiplas linhas e tags de marcação inline.

o bloco do tipo 1 é marcado por um open_tag e um closing_tag mais o nome do bloco, exemplo

START_BLOCK_1 name
   < content >
END_BLOCK_1

blocos do tipo 1 contêm apenas blocos do tipo 2, eles são basicamente usados para ativar ou desativar blocos deste arquivo de configuração.

o bloco do tipo 2 é marcado por uma tag no início de uma nova linha (mais o nome) e não há tag de fechamento, o fechamento é implicitamente feito quando um novo bloco é iniciado ou quando o arquivo termina, o bloco em si é permitido conter linhas vazias.

START_BLOCK_2 name_1
    < content >
    < content >
    < content >

START_BLOCK_2 name_2

    < content >

    < content >
    < content >

START_BLOCK_2 name_3
    < content >
    < content >

o tipo final de token é apenas uma tag inline, uma palavra especial que está presente no início da linha e eu só para saber qual é o valor marcado por essa tag

START_BLOCK_2 name_1

    tag_1 red

    tag_2 Jon

START_BLOCK_2 name_2
    tag_1 blue
    tag_2 Phil

Um bom exemplo final poderia ser

START_BLOCK_2 name_1
    < content >

START_BLOCK_2 name_2

    < content >

START_BLOCK_1 name_1
    START_BLOCK_2 name_3
        < content >

    START_BLOCK_2 name_4

        < content >

END_BLOCK_1

START_BLOCK_2 name_5
    < content >

Considerando os nomes dos blocos do tipo 2, preciso saber os valores associados a cada tag (se eles contiverem tags configuradas) e se eles fazem parte dos blocos do tipo 1 e, nesse caso, o atributo name do tipo 1 bloco que os contém.

O resultado pode ser armazenado em um arquivo ou impresso, contanto que eu possa analisar isso, eu sempre posso reler a saída mais tarde de uma forma formatada.

É relativamente simples analisar esse arquivo, mas nunca fiz isso com apenas um shell GNU / linux e gostaria de saber se isso é possível e os nomes das ferramentas feitas para isso.

EDITAR

entrada

START_BLOCK_2 opt1
color red

START_BLOCK_1 opt2
    START_BLOCK_2 opt3
        name Jon

    START_BLOCK_2 opt4

        color blu

END_BLOCK_1

saída esperada

opt1 red

opt3 opt2
opt3 Jon

opt4 opt2
opt4 blu
    
por user31223 18.11.2016 / 19:02

1 resposta

2

Aqui está uma solução awk , supondo que você não queira as linhas em branco em sua saída de exemplo.

awk '/START_BLOCK_1/ { block1=$2; next; } \
/END_BLOCK_1/ {block1=""; next; } \
/START_BLOCK_2/ { block2=$2; next; } \
/./ { if(block1) {print block2 " " block1} if(block2) { print block2 " " $2}
}' inp

funciona combinando cada linha para um bloco inicial ou final. Se estivermos "em" um BLOCK_1, teremos o nome definido na variável block1 . Se estivermos "em" um BLOCK_2, teremos esse nome definido na variável block2 . Qualquer linha que não defina um bloco e não esteja vazia (corresponde a pelo menos 1 caractere), imprimiremos as coisas com base nos blocos em que estamos.

    
por 18.11.2016 / 19:30