Precisa analisar seções de texto de "agrupamentos" repetitivos de linhas dentro de um arquivo

2

Eu tenho um arquivo que contém de 3 a 5 linhas de informações referentes a uma instância de um grupo de multidifusão e o arquivo contém várias instâncias de grupos de multidifusão:

Group: 239.103.0.64
Source: 10.12.49.30/32
Upstream interface: ge-0/0/7.0

Group: 239.103.0.66
Source: 10.12.49.38/32
Upstream interface: ge-0/0/9.0

Group: 239.103.0.71
Source: 10.12.49.2/32
Upstream interface: ge-0/0/0.0
Downstream interface list: 
    xe-5/0/0.0

Group: 239.103.0.72
Source: 10.12.49.6/32
Upstream interface: ge-0/0/1.0
Downstream interface list: 
    xe-5/0/0.0
    xe-5/0/1.0

Para cada instância, gostaria de produzir 1 linha de saída que contenha o endereço IP de multicast, o endereço IP de origem, a interface Upstream e a lista de interface downstream com os campos delimitados por um ": ". Eu gostaria que a saída para o acima parecesse assim:

239.103.0.64:10.12.49.30/32:ge-0/0/7.0:
239.103.0.66:10.12.49.38/32:ge-0/0/9.0:
239.103.0.71:10.12.49.2/32:ge-0/0/0.0:xe-5/0/0.0
239.103.0.72:10.12.49.6/32:ge-0/0/1.0:xe-5/0/0.0 xe-5/0/1.0
    
por gturney 07.07.2016 / 22:12

3 respostas

0

Não é bonito, mas acho que vai dar certo.

awk -F":" 'BEGIN {RS=""};{$1="";$3=$5=$7=":";gsub(/(\ *)?:(\ *)?/,":");print $0}' test.txt |tr -s " "
    
por 07.07.2016 / 22:54
1
awk '
        /Group:/                     {g=$2; next}
        /Source:/                    {s=$2; next}
        /Upstream interface:/        {u=$3; next}
        /Downstream interface list:/ {dflag=1; next}
        /^$/ {print g ":" s ":" u ":" d; g = s = u = d = ""; dflag = 0; }
        { if (dflag) { if (d == "") d = $1; else d = d " " $1} }
        END  {print g ":" s ":" u ":" d; g = s = u = d = ""; dflag = 0; }
'
  • As primeiras três linhas do programa awk são bastante diretas: capturar os valores do endereço IP Multicast, o endereço IP de origem, e a interface Upstream quando você vê seus rótulos correspondentes.
  • A quarta linha define uma bandeira para que, depois de termos visto o rótulo "Lista de interfaces de recebimento de dados", sabemos que linhas subseqüentes (não vazias) contêm interfaces Downstream.
  • Faz mais sentido olhar para a sexta linha a seguir: Se vimos a etiqueta "Lista de interfaces a jusante", coletar os valores listados, separando-os com espaços.
  • A quinta e a sétima linhas são praticamente as mesmas: Quando você chegar a uma linha em branco ou ao final do arquivo, imprimir os dados coletados até o momento.
por 07.07.2016 / 23:11
0

Se você não se importa com o espaço em branco, você poderia dizer:

awk -v RS='' -v OFS=':' -F'[:\n] *' '{ print $2, $4, $6, $9 " " $10 }'
    
por 08.07.2016 / 12:15